我需要从我的数据库中检索具有许多关系的大型实体层次结构。我没有使用许多 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/

10-13 06:45
查看更多