Today I had the task of querying down a complex set of objects that each own a collection data member. I needed to get to some data 4-layers deep and thought the LINQ query would get pretty nasty. That is until I learned that I can use the "from" keyword multiple times in the same LINQ query.
My example will be very contrived to save having to look at a lot of extra code for different collections, so I'll go ahead and just nest the same collection several layers down, just so we get the concept.
I have a Person class:
public class Person
{
public string FirstName { get; set; }
public string LastName { get; set; }
public int IQ { get; set; }
private List<Person> _children;
public List<Person> Children
{
get{ return _children ?? (_children = new List<Person>()); }
set{ _children = value; }
}
}
List<Person> grandpas = new List<Person>
{
new Person{
FirstName = "John", LastName = "Doe", IQ = 91,
Children = new List<Person>{ // children
new Person{ FirstName = "Meh", LastName = "Doe", IQ = 103 },
new Person{
FirstName = "Tae Kwon", LastName = "Doe", IQ = 125,
Children = new List<Person>{ // grandchildren
new Person{ FirstName = "Karate", LastName = "Kid", IQ = 68, },
new Person{ FirstName = "Karate", LastName = "Kid2", IQ = 117 },
}
},
}
},
new Person{
FirstName = "John", LastName = "Doh", IQ = 135,
Children = new List<Person>{ // children
new Person{ FirstName = "Meh", LastName = "Doh", IQ = 42 },
new Person{
FirstName = "Tae Kwon", LastName = "Doh", IQ = 140,
Children = new List<Person>{ // grandchildren
new Person{ FirstName = "Doh", LastName = "Boy", IQ = 111 },
new Person{ FirstName = "Doh", LastName = "Nut", IQ = 98 },
}
},
}
},
};
IEnumerable<Person> grandChildrenWithHighIQ = from grandpa in grandpas
from parent in grandpa.Children
from grandkid in parent.Children
where
grandkid.IQ > 100
select grandkid;
IEnumerable grandChildrenWithHighIQ = grandpas
.SelectMany(grandpa => grandpa.Children.SelectMany(parent => parent.Children))
.Where(grandchild => grandchild.IQ > 100);
Now we know longer need be afraid of querying complex objects and getting the data we want. Write your queries in the bLINQ of an eye, and get your data back even faster!
And I'll put a shameless plug out there for LINQPad since I took a screenshot from its results above. It is a fantastic tool for crafting LINQ queries and is a wonderful sandbox for small .NET proof-of-concept projects because you can write small programs without creating a Visual Studio project or solution.
Enjoy!