2012-09-04 103 views
0

我在與ObjectContext.LoadProperty(EF 4數據庫優先)難度(無論是字符串和表達重載表現出我相同的行爲)。考慮下面的簡單模式:ObjectContext.LoadProperty不加載相關實體

Product 
-------------- 
ProductId (pk) 
... 

Order 
-------------- 
OrderId (pk) 
... 

OrderItem 
-------------- 
OrderId (pk, fk Order), 
ItemNumber (pk), 
ProductId (fk Product) 
... 

因爲我發現它在我的特殊情況下有更好的表現比Includes,我使用LoadProperty填充相關實體。例如,

Order ord = context.Orders.Where(o => o.OrderId = 1).FirstOrDefault(); 

context.LoadProperty(ord, o => o.Items); // Items is the navigation property name for the 
              OrderItem -> Order relationship 

foreach(var i in ord.Items) 
{ 
    context.LoadProperty(i, oi => oi.Product); 
} 

這已經存在了一段時間,並已工作(如你所料)就好了。然而,今天上午我們開始遇到這樣一個場景,甚至稱LoadProperty後,i.Product仍然無效。 i.ProductId是有效的,我甚至可以明確地裝載產品,像這樣:

var product = context.Products.Where(p => p.ProductId == i.ProductId).FirstOrDefault(); 

LoadProperty將不會加載的對象。沒有異常拋出,它只是不加載它。我也試過指定MergeOptions.OverwriteChanges(即使沒有任何),結果已經可以預見相同。

什麼會導致ObjectContext.LoadProperty以這種方式默默的失敗?

回答

0

我發現這似乎是EF的LoadProperty函數工作方式的一個問題(如果不是徹頭徹尾的錯誤)。

OrderItemProduct表的值爲ProductId,根據大小寫,尾隨空格或兩者不同而不同。鑑於SQL Server的默認排序規則,這是合法的,並且保持了參照完整性。這就是爲什麼該產品的查詢工作,但似乎EF在內部某處做比較,關鍵是和這些價值觀更加嚴格。

如果您自己遇到此問題,可以使用查詢中的T-SQL DATALENGTH函數檢查尾隨空格,並且可以使用不同的排序規則比較大小寫。

例如,您可以使用此看到我上面的型號不符:

select 
    * 

from OrderItem oi 

join Product p on p.ProductId = oi.ProductId -- default collation; case and 
              -- trailing spaces ignored 

where DATALENGTH(oi.ProductId) <> DATALENGTH(p.Product) -- trailing spaces differ 
    or oi.ProductId <> p.ProductId COLLATE SQL_Latin1_General_CP1_CS_AS -- case differs 

注意,有可能既尾隨空格和字符只能使用歸類殼比較;如果有人知道做這樣的事情的排序規則的名稱,請隨時編輯這個答案或發表評論,我會更新。在此之前,這應該做必要的事情。

+0

是EF內部固定關係時匹配的密鑰,但它使用了不帶修剪爲區分大小寫字符串比較。 –