2013-09-27 62 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(); 
} 
相關問題