我正在使用EF4.1并尝试了解正确的加载方法。 我有一个订单输入系统,包含供应商(祖父母),采购订单(父母)和PO2Item(子)表。该模型看起来像
我想从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(如果存在)现在已正确设置供应商。
答案 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));