我需要从我的数据库中检索具有许多关系的大型实体层次结构。我没有使用许多 Includes
创建一个巨大的查询,我读到可以使用许多较小的查询来获取层次结构的不同部分,然后 EF 以某种方式使用称为“关联修复”的东西将所有内容粘合在一起。但是我正在努力让它工作。 (顺便说一下,我正在使用 EF5 和 POCO)。
作为一个简单的例子,我正在尝试使用“修复”技术检索客户及其所有相关订单。这就是我在 BLL 层所做的:-
var customer = context.Customers
.Where(o => o.Id == requestedCustomerId).SingleOrDefault();
customer.Orders = context.Orders
.Where(o => o.CustomerId = requestedCustomerId).ToList();
当我检查返回到 UI 层的客户实体时,customer.Orders 给出一个 ObjectDisposedException。我究竟做错了什么?
作为如何使用 fixup 的进一步示例,我将如何填充订单的相关 OrderLine(在单独的查询中,或作为上述第二个查询的一部分)?如果 OrderLine 实体有一个 ProductCategory 父实体 - 我将如何填充这些?
更新
我刚刚尝试了以下方法,它有效:-
var orders = context.Orders
.Where(o => o.CustomerId = requestedCustomerId).ToList();
var customer = context.Customers
.Where(o => o.Id == requestedCustomerId)
.Include("Orders")
.SingleOrDefault();
我说第二个查询不会再次从数据库中获取订单,EF 会关联上一个查询检索到的订单(即使它们只是位于某个任意变量中),我说得对吗?
最佳答案
ObjectDisposed
异常可能是因为您打开了延迟加载并且您在尝试访问 customer.Orders
之前处理了您的上下文。我不喜欢延迟加载,所以我总是把它关掉:
// in your context constructor:
this.Configuration.LazyLoadingEnabled = false;
您的原始示例现在应该可以工作了。
在您的更新中,您急切地使用
Customer.Orders
子句加载 Include
。这意味着 EF 在获取 join
记录时使用 Customer
从数据库中获取此数据。编辑:
DbContext
“记住”它见过的每个对象,其中一个对象基本上是一个数据库行。如果加载与特定
Orders
关联的 Customer
,则上下文会记住那些 Order
对象。当您随后获取
Customer
对象(没有 .Include( "Orders" )
)时,EF 足够聪明,可以将您之前获取的 Order
对象附加到 Customer
对象。它可以做到这一点,因为
Order
对象有一个 CustomerId
,所以当你得到那个 Customer
对象时,它可以查看它的 CustomerId
属性并将 Order
对象添加到 Customer.Orders
集合中。它只会附加它知道的
Orders
,因此如果您之前由于某种原因没有加载所有关联的 Order
记录,EF 只会附加它所看到的那些记录。关于c# - 如何使用 Entity Framework 关联 "fixup"?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14317526/