I have the following table structure:
Table A, Table B, Table C and Table D where
A 1..* B
A 1..* C
C 1..* D
To begin with I wanted all data returned (via a WCF service so no lazy loading) so this was the original code:
var a = (from a in context.As.Include("Bs").Include("Cs.Ds")
where a.Id = paramId
select a).SingleOrDefault();
This returns an A object with EntityCollections of Bs and Cs and Cs each had an EntityCollection of Ds
However, both B and C have an IsActive flag and I now want to only return Bs and Cs where Active.
I know that I now cannot use .Include as this will always return the entire collection.
After some googling, so far I have:
var query = (from a in context.As
where a.Id = paramId
select new
{
A = a,
Bs = from b in a.Bs where b.IsActive select b,
Cs = from c in a.Cs where c.IsActive select c
}).SingleOrDefault();
Is this the best way to form the query?
I then transform the anonymous type into an A object:
var a = query.A;
foreach (var b in query.Bs)
{
a.Bs.Add(b);
}
foreach (var c in query.Cs)
{
a.Cs.Add(c);
}
Is this the best way to combine the As, Bs and Cs into an A with EntityCollections?
How do I also get the Ds as a collection for every C?
As far as I know, you can’t filter out the included enities: once you write the include, you get all the connected entities.
One of the approaches is to select the connected entities in different collections and track them separately.
On the other hand, you could include the connected collections and apply filtering when you use them.
Please note that your current approach has a drawback:
Your newly created entities are disconnected from context. Which means you’re disabling the self-tracking capabilities when you use them.