I'm using EF to populate objects which I then interact with in my business layer code. The objects have several levels but let's first simplify it to a typical master-detail example with Order and OrderLine.
Let's say I need to retrieve 50 orders each of which has about 100 order lines, and I need all that data. What's the most efficient way of doing this in EF?
If I do it like this:
var orders = context.Orders.Where(o => o.Status == "Whatever")
.Include(order => order.OrderLines)
.ToList();
Then it'll run a single query that pulls back 50x100 rows, then it cleverly assembles that into 50 Order objects, each with their own OrderLine objects.
If instead I don't do the Include() and I later iterate over each Order and its OrderLines, then it'll issue 50 separate queries to get the OrderLine data, i.e. one for each Order.
So far the .Include() seems great: I pull back a bit more data than needed from SQL but that's much better than issuing 50 extra queries. But is there a way I can choose to issue 2 queries, one to get Order and one to get OrderLine, and have EF connect the objects automatically?
A more realistic scenario where I want this is if the data is more complex. Let's say I want objects like this (where Product is the thing being bought in the OrderLine and ProductPart is a number of bits used to make the Product):
- Order
- OrderLine (avg 100 per Order)
- Product (1 per OrderLine)
- ProductPart (avg 20 per Product)
Now if I do a .Include() with ProductPart, it'll make the query results much bigger. Or if I don't Include() then it'll issue separate queries for each Product.
Is there a third way where I can get all the Order, OrderLine and Product data in one query and all the ProductPart data in another query, and magically have EF connect the objects up for me?
UPDATE:
I just read about AsSplitQuery() which seems to be what I'm looking for but is only available in EF Core 5 which isn't stable till Nov 2020 (?). I'm looking for a way to achieve this in EF6.
A bit more research and I found https://entityframework.net/improve-ef-include-performance which suggests two approaches when you have multiple object types coming off the parent object:
Execute multiple EF commands to pull back the same list of parent objects, but each time
Include()-ing different child object types. EF will hook up the related objects it's already pulled from the db, apparently.Use the EF+ library which seems it can do something like
AsSplitQuery()
I'm not sure if this works with my case where there's more levels of nesting rather than just different types of objects off the parent. My guess is yes, if I'm clever about it. Any tips?