views:

23

answers:

2

Hello everybody,

I have two tables: A & B

B { B1: Field1, B2: Field2, ... }

A { Children: List of B, A1: Field1, A2: Field2, }

I want to retrieve "A" entities with related "B" entities like this:

DataContext.A.Select( a => new MySubset( A1 = a.A1, Children = a.Children.Select(b => b.B1).ToList());

But EF can't translate ToList into SQL, so i have to call ToList() per each instance in query producing additional network call.

How can I avoid this?

Thank you in advance.

A: 

I would use IEnumerable instead of List in the constructor of MySubset.

Or: Create the List not by .ToList(), but by new List<T>(a.Children.Select(b => b.B1))

Femaref
Andrew Florko
edited something in. Even your .ToList() in the original statement would produce another network call.
Femaref
Sorry, but only paremeterless constructors are allowed in EF. I am looking into eager loading (.Include method)
Andrew Florko
A: 

You can use an .Include statement to do eager loading:

http://msdn.microsoft.com/en-us/library/bb896272.aspx

Explanation

Assuming you are on VS2010 and Lazy Loading is enabled:

When you load A initially there's a collection of B's apparently waiting for you off A, but it's not really, it's not a List<>, its an object that knows how to provide the B's when you ask for them. Only when you access this collection will EF do the round trip to the database to fetch it.

But if you use .Include() you can request that it fetches B at the same time as it fetches A.

Hightechrider
Sorry, it looks like the related (List of "B") entities that are included as navigation properties are already in the outmost projection.How can I make sure with my SQL Express Studio that it's true? I stop the database after "A" entity is retrieved and it's "B" collection is accessible with stopped Database. Look's like "B" are retrieved with "A" at one call.
Andrew Florko
I added an explanation for you - this collection of B's hasn't been instantiated if you fetched just the A.
Hightechrider
Thank you for the explanation but what about if projection of "A" properties is fetched. "MySubset" has "A" properties and IEnumerable<B> property as well.
Andrew Florko
You may store it as IEnumerable<B> but what EF actually gives you is EntityCollection<B>. An IEnumerable<X> typically doesn't do anything until you start enumerating it. And in this case when you ask the EntityCollection<B> for the first item it will go lazy load the collection if you haven't asked it to eager load using .Include("B").
Hightechrider
Thank you. Solution works perfectly :)
Andrew Florko