2013-09-27 61 views
3

我对某个父实体(Order)有一个查询,我想加载它的一些子集合或属性。我有这样一个查询:实体框架5渴望加载父项属性

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,但我不能从ProductVariantOrderProduct。我想知道为什么我得到这个错误,尽管我把OrderProduct.ProductVariant加入到我的加载属性中。它不是应该两种方式?

任何帮助将非常感激。

+0

这是1:1映射? –

+0

映射如下:Order to OrderProduct 1:N and OrderProduct to ProductVariant 1:1 – ayk

回答

1

您在上下文之外获得ObjectDisposedException的事实表明实体框架尝试加载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(); 
} 
相关问题