Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Order by with Linq + Include

Tags:

c#

include

linq

I have a One-Many relation with two Entities :

Order:
int OrderId 
string OrderNumber
...

OrderItem:
int ItemId
int sequence
...

Product:
int ProductId
string ProductName

ProductType:
int ProductTypeid
string Title

One Order Has multiple OrderItems, and each OrderItem has One Product and each Product has one ProductType.

I want to write a Linq that return all orders with their items,Product,ProductType and items be sorted by sequence field. How can I write a query such as following query?

with help from Order by with Linq i wrote this query:

var myOrder= db.Orders.Include("OrderItems")
         .Where(x => x.OrderId == 3)
         .Include("OrderItems.Product") 
         .Include("OrderItems.Product.ProductType") 
         .Select(o => new {
             order = o,
             orderItems = o.OrderItems.OrderBy(i => i.sequence)
         }).FirstOrDefault();

but when it return the result, it doesn't contain Product and ProductType data. where is my mistake?

like image 636
Masoud Avatar asked Jan 23 '13 10:01

Masoud


Video Answer


1 Answers

You need to put all calls to Include() first. This should work:

var myOrder= db.Orders.Include("OrderItems")
     .Include("OrderItems.Product") 
     .Include("OrderItems.Product.ProductType") 
     .Where(x => x.OrderId == 3)
     .Select(o => new {
         order = o,
         orderItems = o.OrderItems.OrderBy(i => i.sequence)
     }).FirstOrDefault();

Also, when you have .Include("OrderItems.Product.ProductType"), you do not need .Include("OrderItems") and .Include("OrderItems.Product"), because it will include OrderItems and their products on the way to including product types. It has to do this or you would be unable to navigate to them in code -- what would it attach them to?

In this case, it looks as though this might explain it: http://wildermuth.com/2008/12/28/Caution_when_Eager_Loading_in_the_Entity_Framework

You can get around without using includes:

var query = db.Orders
.Where(x => x.OrderId == 3)
.Select(o => new {
order = o,
orderItems = o.OrderItems.OrderBy(i => i.sequence),
products = o.OrderItems.Select(i => new { i, i.Product, i.Product.ProductType })
});

Anything you project into your output select will be automatically eager-loaded. Eager loading like this is actually preferable in some ways, because you are only materializing what you need, rather than the full object graph. (Although in this case we're materializing the same as what the include would.)

like image 152
Bennor McCarthy Avatar answered Nov 03 '22 01:11

Bennor McCarthy