I’m wanting to retrieve a set of objects (A) and a number of related objects (B) within a single query. There are no navigation properties on A and B so I believe I need to use this syntax:
select a from db.As where a.Id = x select new AndBHolder
{
A = a,
Bs = select b from db.Bs where b.ASomeId == A.SomeId select b
}
I’m not sure if this is the best way, but it does work. However I now need to include a property of B (a list of Cs). I wasn’t expecting it to work but I tried:
select a from db.As where a.Id = x select new AndBHolder
{
A = a,
Bs = select b from db.Bs.Include("Cs") where b.ASomeId == A.SomeId select b
}
Which fails with “Method … Include declared on type … cannot be called with instance of type …”. Next I thought I’d try a projection within a projection:
select a from db.As where a.Id = x select new AndBHolder
{
A = a,
Bs = select b from db.Bs where b.ASomeId == A.SomeId select new B
{
Id = b.Id,
// ...
Cs = select c from db.Cs where c.BId == b.Id select c
}
}
Which fails with “The entity or complex type ‘B‘ cannot be constructed in a LINQ to Entities query” because you are not allowed to project into a mapped object. So how do I retrieve the Bs with their Cs populated, or is the secondary level inclusion just not supportted? Am I just going to have to make two calls to the database, one to retrieve the As and one to retrieve the Bs with their Cs?
If you use a projection with
select newyou can’t useIncludeanymore, it will be ignored. Instead you must add the related entities to the projected data, for example:If the relationship between
BandCis one-to-many (not many-to-many) EF should populate theCscollection in every loadedBautomatically (that’s called “relationship fixup”) which means that you could throw away theCsfrom the projection after the data have be loaded from the database. To put this together you can try to write the query like so: