如何在EF 4.1中急切加载祖父母记录

时间:2011-11-17 21:59:03

标签: c# linq entity-framework-4.1

我正在使用EF4.1并尝试了解正确的加载方法。 我有一个订单输入系统,包含供应商(祖父母),采购订单(父母)和PO2Item(子)表。该模型看起来像ModelScreenImage

我想从PO2Item记录开始并加载供应商。我想我可以像这样使用 .Include()

var po = (from item in context.PO2Item.Include("PurchaseOrder.Vendor").AsNoTracking()
            where item.OrderLineItemId == lineItem.CostSourceLineItemId
            select item.PurchaseOrder).FirstOrDefault();

这会加载PurchaseOrder记录,但po.Vendor为null。我正在阅读Julia Lerman的书,第4章表明我可以使用Load,但我认为4.1必须从4.0改变这一点,因为Load似乎没有定义,也没有VendorReference这样的东西。最后我挖到了ObjectContext并且能够做到这一点:

   if (po!=null)
   {
       context.GetObjectContext().LoadProperty(po, "Vendor");  
   }

确实加载了供应商,但我感觉我错过了一些更简单的东西。为什么不包括(“PurchaseOrder.Vendor”)工作?

根据克雷格的回答更新。

而不是将结果转换为ObjectQuery<> (一个很酷的小技巧),我只是分两个阶段写了

var links = from link in context.PO2Item.Include("PurchaseOrder.Vendor").AsNoTracking()
            where link.OrderLineItemId == lineItem.CostSourceLineItemId
            select link;

var po_2_item = links.FirstOrDefault();
return po_2_item == null ? null : po_2_item.PurchaseOrder;

返回的PO(如果存在)现在已正确设置供应商。

请参阅this answer以获得更优雅的解决方案。

2 个答案:

答案 0 :(得分:2)

.Include()适用于返回查询的形状。

您的查询返回PurchaseOrder,而不是PO2Item

你需要更多类似的东西(猜测这里的类型 - 你可能正在使用DbSet - 相应调整):

var po = ((ObjectQuery<PurchaseOrder>)
         (from item in context.PO2Item
          where item.OrderLineItemId == lineItem.CostSourceLineItemId
          select item.PurchaseOrder))
         .Include("Vendor")
         .AsNoTracking()
         .FirstOrDefault();

答案 1 :(得分:1)

我知道这已经回答了,但为什么不这样做呢?

// Get the purchase order (with Vendor) that has the given PO2Item
var po = context.PurchaseOrder.Include("Vendor").AsNoTracking().FirstOrDefault(
    o => o.PO2Item.Any(i => i.OrderLineItemId == lineItem.CostSourceLineItemId));