2011-09-07 32 views
3

我正在嘗試將一些多線程添加到我創建的WPF應用程序中,以創建響應性更好的接口,但由於Linq-to-SQL數據上下文不是線程安全,我被迫每個線程使用一個。實體在不同Linq-to-SQL上下文中的相等性

我的問題是,從兩個不同的上下文拉同一個實體,顯然是不相等的。看看下面的代碼示例,在這裏我有一個簡單的數據庫與員工記錄:

var context1 = new DataModelDataContext(); 
var context2 = new DataModelDataContext(); 

var emp1 = context1.Employees.Single(x => x.ID == 1); 
var emp2 = context2.Employees.Single(x => x.ID == 1); 

Console.WriteLine(string.Format("Employees equal: {0}", emp1 == emp2)); 
Console.ReadKey(); 

運行時,這將返回:

Employees equal: False 

在我心中我希望這些對象是相等的,如如果我將它們從相同的環境中拉出來,他們會是。我可以通過檢查emp1.ID == emp2.​​ID來解決此問題,但嘗試使用WPF綁定時會出現問題,例如SelectedItem

有沒有辦法解決這個問題?這種行爲在實體框架中看起來也是一樣的。

回答

1

您可以始終覆蓋EqualsGetHasCode以確保即使它們不是相同的實例(這是用於引用類型的默認相等性規則),它們也是「相等的」。

2

兩個獨立實例化的對象可能表示數據存儲中的相同項目,但它們絕不會在任何語言中評估爲相等。您將不得不編寫比較每個對象成員的代碼,以確定它們的數據是否相等。這可能或可能不如比較主鍵那麼簡單。

+0

+1只是想寫相同。 op只是給出了自己的答案:''emp1.ID == emp2.​​ID''將完成這項工作(如果''''''''是唯一的主鍵或課程) –

+0

覆蓋平等似乎是要走的路 –

0

正如@cdonner所說,當你從數據存儲中加載一個對象時 - 對象的兩個不同的實例將被創建爲相同的數據。這將意味着object1!= object2。

克服此問題的一種方法是在存儲庫中設置一個像字典一樣的緩存。例如:Dictionary<Type, object>其中object是您的標識符的類型(在本例中爲int)

因此而不是查詢數據存儲使用像context1.Employees.Single(x => x.ID == 1);內嵌代碼,你可以設定,讓你這樣稱呼它Repositories.Employees.WithID(1);

這是什麼會那麼做的是檢查本地倉庫緩存與ID == 1Employee對象,如果這是可用的返回它而不是查詢數據存儲。

從此,您的參考文獻將始終如一。

這可能需要進行一些改進,以便在您想要更新和/或從數據存儲中刷新內存中的對象時,以便不會持續陳舊的數據,並且從數據存儲刷新數據時,你更新緩存。

相關問題