【问题标题】:How to manually load EntityReference without using EntityReference.Load()如何在不使用 EntityReference.Load() 的情况下手动加载 EntityReference
【发布时间】:2009-06-13 13:43:07
【问题描述】:
我有一个实体类型 Order,它引用了一个实体类型 Customer。
有一个函数 import 可以根据条件返回 Order 列表。此订单列表显示在显示的 Datagrid 中
订单.日期 |订单.客户.名称 |订单总数
为了让 Customer.Name 出现,我需要在列表中的每个 Order 中加载 CustomerReference,但是每次调用 Order.CustomerReference.Load() 都会往返 SQL Server 并使整个过程非常低效.问题是,如果我有一个查询来检索列表中所有订单的所有客户数据,我如何手动填充每个订单中的 CustomerReference?
基本上我需要用函数导入来做 .Include("Customer")。
谢谢
【问题讨论】:
标签:
.net
entity-framework
ado.net
【解决方案1】:
如果您执行一个一次性带回所有相关客户的查询,则无需手动填充每个 CustomerReference。这是因为称为关系修复的东西会自动为您完成此操作。
即如果你这样做:
Order o = ctx.Orders.First(o => o.Customer.ID == 1);
// at this point o.Customer == null
Customer c = ctx.Customers.First(c => c.ID == 1);
// at this point o.Customer == c
Relationship Fixup 意味着在客户进入上下文后,所有相关对象现在都会自动指向它...
即这比你想象的要容易得多!
希望对你有帮助
亚历克斯
【解决方案2】:
谢谢亚历克斯,我试过了。它可以按您所说的那样工作,但显然它不适用于派生实体类型。 Order Entity Type 是一个抽象基类,它有一个派生类 Sale。
Order o1 = ctx.Orders.First(o => o.Customer.ID == 1);
Sale s1 = ctx.GetSaleByCustomerID_FunctionImport(2).First();
Customer c = ctx.Customers.First(c => c.ID == 1);
Customer c2 = ctx.Customers.First(c => c.ID == 2);
//At this point o.Customer == c but s1.Customer is still null
而且我不能将函数导入返回类型设置为 Order,因为它是抽象的并且不允许作为返回类型。
我在这里错过了什么?
更新:
在加载客户之前,我发现 o1 和 s1 之间存在差异
o1.CustomerReference.IsLoaded 为 False
o1.CustomerReference.EntityKey 是 ID = 2
s1.CustomerReference.IsLoaded 为假
s1.CustomerReference.EntityKey 为空
但调用 s1.CustomerReference.Load() 会正确加载客户数据。
我仔细检查了我的 GetSaleByCustomerID 函数导入(简单地说“SELECT * FROM Customers WHERE ID = 2”),它确实返回了引用所需的 CustomerID 字段。