繁体   English   中英

实体框架5急切加载父属性

[英]Entity Framework 5 eager loading with parent properties

我有一些父实体( Order )的查询,我想热切地加载它的一些子集合或属性。 我有这样的查询:

public void QueryMethod()
{
    using (var context = new MyContext())
    {
        var orders = context.Order.Include("OrderProduct")
                                  .Include("OrderProduct.ProductVariant")
                                  .Where(some query)
                                  .ToList();
    }
}

我正在做的是循环遍历此订单集合,对于每个Order我都会访问OrderProductProductVariant属性。 当上下文处于活动状态时,我可以在查询方法中执行此操作。 但是当我尝试在上下文之外访问ProductVariant.OrderProduct ,我得到了ObjectDisposedException

顺便说一下,我试图访问ProductVariant.OrderProduct有一些奇怪的原因。 我想我不应该这样访问它,但我的观点是我可以从OrderProductProductVariant ,但是我无法从ProductVariant访问OrderProduct 我想知道为什么我得到这个错误,尽管我将OrderProduct.ProductVariant添加到我的渴望加载属性中。 它不应该双向工作吗?

任何帮助将非常感谢。

您在上下文外部获得ObjectDisposedException这一事实表明Entity Framework尝试通过数据库中的延迟加载来加载ProductVariant.OrderProduct引用的对象。

现在,这并不一定意味着 - 这个陈述听起来很奇怪 - ProductVariant.OrderProduct尚未加载并填充正确的实体。 也许这是因为它的是相反的属性OrderProduct.ProductVariant通过预先加载加载。 对于一对一和一对多关系,EF将在加载导航属性时自动填充反向导航属性(“关系修正”)。

尽管填充了反向导航属性,但它不一定标记为已加载 ,这是由每个导航属性的上下文维护的标志,它告诉EF当您在代码中访问它时是否必须通过延迟加载从数据库加载导航属性。

例如,对于一对多关系,很容易看出EF由于关系修正而在填充时不得将导航属性标记为已加载。 例如:如果您加载包含其客户引用的订单 - context.Orders.Include("Customer").Single... - 急切加载的客户中的Orders集合将包含此加载的订单(因为关系修正)。 但是这个单一订单很可能不是该客户唯一的订单(或者至少EF不知道这是唯一订单还是数据库中有更多订单)。 如果您访问Customer.Orders集合,您通常期望不仅返回此单个订单而且还返回客户的所有订单 - 换句话说,您希望发生延迟加载查询,从数据库加载客户的其余订单。

现在,这个论点并不能真正说服一对一的关系,因为对于这种关系,很明显数据库中不能有多个相关对象。 那么,如果已经加载了这个单个相关对象,为什么EF想要运行延迟加载查询?

我不知道为什么EF仍然试图为一对一关系加载逆导航属性,但是在这方面它只是不区分一对多关系和一对一关系。 也许EF遵循一般规则,即如果关系的主要方面由关系修正填充,则它不会被标记为已加载,并且在您访问它时,任何情况下都会发生延迟加载。 (我无法从你的代码片段中看到,如果OrderProductProductVariant是主体,那只是猜测。)

无论如何,在你的情况下,我会禁用延迟加载甚至代理创建(包括禁用延迟加载),因为你在using块中使用Include并且延迟加载在这里没有任何好处。 你所拥有的例外应该会消失:

using (var context = new MyContext())
{
    context.Configuration.ProxyCreationEnabled = false;

    var orders = context.Order.Include("OrderProduct")
                              .Include("OrderProduct.ProductVariant")
                              .Where(some query)
                              .ToList();
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM