Creating a sublist from a parent list - c#

I have a collection of custom objects, dependents. The custom object has about 70 properties. I want to extract just one property, the membernumber. I have the following code, where I am extracting the membernumbers and creating another list:
var memberIDs = (from d in dependents
select new
{
d.MemberNum
});
foreach(var id in memberIDs)
{
string idValue = id.ToString();
}
The problem is that idValue comes as "{ MemberNum = 20044782604 }" instead of just the "20044782604". Please let me know how to resolve it.
Thanks

That's because you are creating a new anonymous type with the MemberNum as a property. Just select it instead.
var memberIDs = from d in dependents
select d.MemberNum;
This will yield an IEnumerable<int> instead of an IEnumerable<AnonymousType> (assuming MemberNum is of type int).

Related

Linq return type conversion

I have a linq query as follows,
var result =
from Record in DBContext.GetAll().
group new { Record.Filed1, Record.Field2} by Record.Field3
into newGroup
select new
{
BodyRegion = newGroup.Key,
ByScanner =
from exam in newGroup
group exam.MaxValue by exam.Model
into myGroup
select myGroup,
ByExam =
from exam in newGroup
group exam.MaxValue by exam.Protocol
into myGroup2
select myGroup2
};
Then I iterate throught them,
foreach (var rec in result)
{
foreach (var byScanner in rec.ByScanner)
{
ProcessResult(byScanner.Key, byScanner.ToList());
}
foreach (var byExam in rec.ByExam )
{
ProcessResult(byExam.Key, byExam.ToList());
}
}
Everything works fine.
But Iwant to move Linq query (first code snippet) to a function, what should be the return type the function?
Return type of a function can not be var. If I give IEnumerable< Object > then while iterating I can't access rec.ByScanner, rec.ByExam because Object doesn't contain them.
How to resolve this issue?
EDIT:
I tried by creating a new class and filling them in that. But Grouping attributes byScanner.Key, byScanner.ToList() are not accessible. How this can be solved?
You are using an Anonymous Type. These shouldn't be passed around methods.
One thing you can do is create (Let's call it 'Record') a class with properties BodyRegion, ByScanner and ByExam and pass IEnumerable<Record>.

How to access Individual elements of an object list which converted from a LINQ operation after passing to another method?

I have a LINQ list as follows
var lst = (from entity in Entities
join entity2 in E2.x equals Entities.x
select entity);
2 . And um doing this after the above operation.
return lst.ToList<Object>()
and from another method um accessing this list like this.
List<Object> listObjects = new MyBO().GetAllEntities();
please note that number 2 is in the GetAllEntities method
but from listObjects by iterating listObjects I cannot access the members in individual element .
How to access the individual elements?
this is the output returned from GetAllEntities()
[0] { id= XCD1S100001, Type = EXPORT}
[1] { id= XSD1S100001, Type = IMPORT}
How to acccess listObjects[0].getType() or listObjects[0].Type because it won't give such a method.
Please need a hand.
In first statement you use var keyword:
var lst = (from entity in Entities select entity);
That makes lst the most suitable type, which is IEnumerable<Entity> (class name can be different, I'm just guessing here).
On the second approach you set the output as List<object> by yourself:
`return lst.ToList<Object>()`
and
List<Object> listObjects = new MyBO().GetAllEntities();
And that's why you can't directly get Entity class members there - Object instance does not have a property Type.
`return lst.ToList();`
hange it to var :
var listObjects = new MyBO().GetAllEntities();
You'll have to change method return type to List<Entity> as well.
What is type of entity in Entities collection? Why you are converting it to List of object? Try:
lst.ToList()
instead of:
lst.ToList<Object>()

Add property to an item in a list

So I'm just starting out with ASP.NET MVC, and I've run into an issue I just can't find an answer to.
I'm grabbing some data from an SQL database, and send it to the view with this code:
var listingsQuery = (from s in db.tblListings select s).OrderBy(s => s.listingID).Skip(100).Take(25);
var listings = listingsQuery.ToList();
return View(listings);
This works great, but I want to add a value in the list of results. Basically what I'm trying to do is something like this:
foreach (var item in listings)
{
this.Add("propertyType", "Home");
}
But obviously that doesn't work. I've tried doing ToArray() instead of ToList() and that got me nowhere.
Do you want to add a new property to each object in the List collection? If so, you can create a new type that inherits from whatever object type is in the list (hover over the listingsQuery variable - the type is inside the <> symbols) and add the new property to it:
public class MyNewType : ExistingTableType
{
public string PropertyType { get; set; }
}
Then inside of your query, project the properties into this new type:
var listingsQuery = (from s in db.tblListings
orderby s.listingID
select new NewType
{
listingID = s.listingID,
someOtherField = s.someOtherField
}
).Skip(100).Take(25);
Now you can cycle through each record and assign a value:
foreach(var record in listings)
{
record.ProperyType = "Home";
}
There are other ways of doing this as well (assuming you're using EF), for example, if you used raw SQL you can cast the result type directly into the new type (without having the map each field), but this should get you started.
If you want to add a new row to your listings collection you need to do listings.Add instead of this.Add
If you want to modify a value in your listing collection then you need to do
foreach(var item in listings)
{
item.PropertyName = value;
}

Is it possible to get other collection than IEnumerable<T> when using LINQ: XML to object?

So I have this huge XML file that I am converting to an object by using LINQ. And currently I am doing:
var resultStories = from story in resultXML.Descendants("story")
select new NewsStory
{
ArticleFrequency = from tag in story.Descendants("tag")
select new KeyValuePair<string,int>((string)tag.Element("name"),(int)tag.Element("count"))
};
Now this gives creates a IEnumerable<KeyValuePair<String,int>> for me. But I am wondering if it is possible to get another collection such as a Dictionary<String,int> or List<new MyItem(string key, int value) ?
I have this huge LINQ book and it only contains information about Objects to XML.
This question pertains XML to Objects.
Thank you :)
Yes this is possible using Linqs ToDictionary method.
You should be able to say
ArticleFrequency = (from tag in story.Descendants("tag")
select new
{
Key = (string)tag.Element("name"),
Value = (int)tag.Element("count")
}).ToDictionary(val => val.Key, val => val.Value)
Your ArticleFrequency property will of course need to be of type IDictionary<string, int>
UPDATE To answer your question in the comments (if I understand correctly), just change the Select to return an Enumerable of the desired type e.g.
ArticleFrequency = (from tag in story.Descendants("tag")
select new MyCustomObject()
{
MyPropertyOne = (string)tag.Element("name"),
MyPropertyTwo = (int)tag.Element("count")
})
will assign an IEnumerable<MyCustomObject> to ArticleFrequency. If you are saying you want ArticleFrequency to be of type Stack you can just wrap the whole Linq query and use it as the IEnumerable parameter to the Stack constructor overload e.g.
ArticleFrequency = new Stack<KeyValuePair<string, int>>(
(from tag in story.Descendants("tag")
select new KeyValuePair<string, int>()
{
Key = (string)tag.Element("name"),
Value = (int)tag.Element("count")
}))
You can get it to return a Dictionary like so:
ArticleFrequency = story.Descendants("tag").ToDictionary<XElement, string,int>()(
tag=>(string)tag.Element("name"),
tag=>(int)tag.Element("count")
);

Cast Object to Generic List

I have 3 generict type list.
List<Contact> = new List<Contact>();
List<Address> = new List<Address>();
List<Document> = new List<Document>();
And save it on a variable with type object. Now i nedd do Cast Back to List to perfom a foreach, some like this:
List<Contact> = (List<Contact>)obj;
But obj content change every time, and i have some like this:
List<???> = (List<???>)obj;
I have another variable holding current obj Type:
Type t = typeof(obj);
Can i do some thing like that??:
List<t> = (List<t>)obj;
Obs: I no the current type in the list but i need to cast , and i dont now another form instead:
List<Contact> = new List<Contact>();
Lots of trial and error gave me this on SL 5 but it should also work on a regular C#. You also need to add LINQ to your using list for the last half to work.
List<object> myAnythingList = (value as IEnumerable<object>).Cast<object>().ToList()
Enjoy!
What a sticky problem. Try this:
List<Contact> c = null;
List<Address> a = null;
List<Document> d = null;
object o = GetObject();
c = o as List<Contact>;
a = o as List<Address>;
d = o as List<Document>;
Between c, a, and d, there's 2 nulls and 1 non-null, or 3 nulls.
Take 2:
object o = GetObject();
IEnumerable e = o as IEnumerable;
IEnumerable<Contact> c = e.OfType<Contact>();
IEnumerable<Address> a = e.OfType<Address>();
IEnumerable<Document> d = e.OfType<Document>();
I had the same problem and solved it by looking at the purpose of the casted objects. Do you really need to cast it to the specific (closed) generic types? In my case the (open) generic type had an interface which I used to cast it to.
var list = obj as IUsefulInterface;
list.MethodThatIAmInterestedIn();
I had this problem when writing a Validation Attribute where I received an object from the ValidationContext and knew that it needed to be a list, but not what it was a list of. It threw an exception when I tried to cast it as IEnumerable<object> but it could be cast as IEnumerable which then allowed the .Cast<object>() via linq.
In the end what worked was:
var enumerable = listObject as IEnumerable;
var list = enumerable.Cast<object>().ToList();
A general solution like this (to instantiate a type with a generic parameter based on a System.Type object) is not possible. If you're really just dealing with these three types, though, then you're in luck because it's pretty easy:
Type t = typeof(obj);
if (t == typeof(List<Contact>)) {
var contactList = (List<Contact>)obj;
// do stuff with contactList
} else if (t == typeof(List<Address>)) {
var addressList = (List<Address>)obj;
// do stuff with addressList
} else if (t == typeof(List<Document>)) {
var documentList = (List<Document>)obj;
// do stuff with documentList
}
No, you can't cast without going around corners (this is: reflection), generic type parameters have to be known at compile time. You can of course do something like this:
content.Where(o => o is type).ToList().Foreach(stuff);
I ran into same problem - I have a collection which data type is only known at run time and I can't cast it to anything. None of the solutions above worked. Finally I solved it by serializing to JSON and de-serializing back. Of course it's not ideal, but may help someone.
string jsonString = JsonConvert.SerializeObject(myObject);
jsonString = "{ values:" + jsonString + "}";
JObject j = JObject.Parse(jsonString);
//now we can iterate over the list
foreach (var x in j["values"])
{
string name = x.ToString();
...
}
Employee employee=new Employee();
List<Employee> emplist=new();
emplist.Add(employee);
This is correct way
Thank you
You might need to do:
if(object is List)
{
list = (List)object
}

Categories

Resources