开发者

Strongly typed include in entity framework 4

Let's say I have tables Order, and OrderLines. I'm using ef4 "include" to load the OrderLines. Unfortunately as the OrderLines is referenced as a string I'm not able to expose any of its properties. So in shor开发者_开发百科t, if OrderLines has properties cost and size, can these be referenced? for example something like this, but realise I can't:

           orders= from Orders o in 
                       db.Orders.Include("OrderLines")
                      where o.OrderId == this.OrderId
                         select new() 
                  { 
                     o.cost
                     o.size
                  }

If not, how would I acheive this?

Thanks

Stu


It depends if you want to filter the result set based on the OrderLines or simply access it from the result set.

Say if you wanted a list of Orders (with OrderLines included), where the OrderLines cost at least $10.00 and a size of 5. You could do this:

var orders = ctx
               .Orders
               .Include("OrderLines")
               .Where(x => x.OrderLines.Any(y => y.Cost >= 10.00 && y.Size == 5))
               .ToList(); // result is List<Orders> with OrderLines populated.

If you only want the OrderLines, then project the orderlines:

var orders = ctx
               .Orders
               .Include("OrderLines")
               .Where(x => x.OrderLines.Any(y => y.Cost >= 10.00 && y.Size == 5))
               .Select(x => x.OrderLines)
               .ToList(); // result is List<OrderLine>

Your projection was returning a List of anonymous types, with two properties. You need to pull back the strongly-typed object, like this:

var orders = ctx
               .Orders
               .Include("OrderLines")
               .ToList(); // result is List<Orders> with OrderLines populated

Now, OrderLines will be exposed as an ICollection<T> on each order.

E.g

foreach (var order in orders)
{
   Console.Write("Order Id: " + order.OrderId);
   foreach (var orderLine in order.OrderLines)
   {
         Console.Write("Order Line: " + orderLine.OrderLineId);
         Console.Write("Order Line Cost: " + orderLine.Cost);
   }
}


The Include method on an object set like Orders is going to "eager-load" that data so that the OrderLines instances associated with each Order instance is fetched at the same time and save you a trip to the DB.

Each OrderLine instance retrieved will have all of it's scalar properties automatically retrieved so yes, cost and size (which I'm assuming are scalars) will be retrieved. Now if OrderLine has another navigation property on it (another entity referenced as a property on OrderLine) such as say OrderLine.Product which is from the Products table, then it won't be retrieved. If you want to also eager-load that property of OrderLine, you could do the following:

from Orders o in db.Orders
                   .Include("OrderLines")
                   .Include("OrderLines.Product")
                  where o.OrderId == this.OrderId
                     select new() 
              { 
                 o.cost
                 o.size
              }
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜