假設我在搜索表中輸入條目時遇到性能問題。我們舉個例子:EF Code First - 搜索具有特定屬性值的特定行 - 性能
public class A {
[Key]
public int Id {get;set;}
public string xyz {get; set;}
}
public class Context : DbContext {
public DbSet<A> AList {get;set;}
public A FindA(string xyz) {
A output = null;
if(AList.Local != null) {
output = AList.Local.SingleOrDefault(x=>x.xyz==xyz);
}
return output ?? AList.SingleOrDefault(x=>x.xyz==xyz);
}
}
方法FindA首先在本地集合中查找,如果沒有匹配,它將轉到數據庫。我需要這種方法來避免重複插入元素。
這種方法的問題很簡單:對AList.Local的搜索具有O(n)複雜性,在我的情況下,AList.Local通常大於100,000條記錄。如果AList.Local是一個在xyz屬性上索引的字典,那就太好了;然而,EF Code First IDbSet使用ObservableCollection,根本沒有索引。
一種可能的解決方案是將字典保留爲AList.Local的鏡像。但是,這很棘手,因爲對AList.Local的更改不容易追蹤。
另一種解決方案是使xyz屬性成爲主鍵並使用AList.Find(xyz)方法(我希望它是O(1)搜索,即使實體位於本地緩存中)。然而,我懷疑使用一個字符串作爲主鍵會影響我的數據庫的性能,並增加很多索引文件的大小。
誰能給我一個關於如何克服這種情況的建議?
爲什麼更改'Local'集合不容易跟蹤?它是'ObservableCollection',所以你可以很容易地訂閱它的'CollectionChanged'事件並且被通知所有的改變。 –
另外,如果您的本地圖中有100k項,那麼您可能會遇到麻煩,因爲任何EF操作(例如添加單行)都將爲O(N)。國際海事組織,你會好得多不跟蹤這些與EF的實體,而是存儲在散列表中最小的表示(如只是ID + xyz屬性)。 –