3

我需要从我的数据库中检索具有许多关系的大型实体层次结构。我没有用许多创建一个巨大的查询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 的另一个示例,我将如何填充 Orders 的相关 OrderLines(在单独的查询中,或作为上面第二个查询的一部分)?如果 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 会将前一个查询检索到的那些关联起来(即使它们只是位于某个任意变量中)?

4

1 回答 1

4

例外情况可能是因为您打开了延迟加载,ObjectDisposed并且您在尝试访问customer.Orders. 我不喜欢延迟加载,所以我总是把它关掉:

// in your context constructor:
this.Configuration.LazyLoadingEnabled = false;

您的原始示例现在应该可以工作了。


在您的更新中,您急切地加载Customer.OrdersInclude子句。这意味着 EF 在join获取记录时使用 a 从数据库中获取此数据Customer


编辑:

A DbContext“记住”它看到的每个对象,其中一个对象基本上是一个数据库行。

如果您加载Orders与特定对象关联的内容,Customer则上下文会记住这些Order对象。

当您随后获取Customer对象(没有.Include( "Orders" ))时,EF 足够聪明,可以将Order您之前获取的对象附加到该Customer对象。

它可以做到这一点,因为Order对象有一个CustomerId,所以当你得到那个Customer对象时,它可以查看它的CustomerId属性并将Order对象添加到Customer.Orders集合中。

它只会附加Orders它知道的信息,因此如果您之前由于某种原因没有加载所有相关Order记录,EF 只会附加它看到的那些。

于 2013-01-14T11:46:51.857 回答