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
}
精彩评论