EF Core 一對多關係:ICollection 還是 Hashset?
我正在閱讀 Jon P Smith 的“Entity Framework Core in Action”。那裡說:
當 Hashet 是正確的集合類型時,您能否提供一些範例?為什麼?
**更新:**我剛剛完成了我的書Entity Framework Core in Action 的更新,並且我做了一些性能測試,表明
HashSet<T>如果您進行普通查詢(即沒有AsNoTracking在查詢中)會更快。這是因為 EF Core 做了一些稱為身份解析的事情(在我的一篇文章中了解了這一點),非 HashSet 集合的速度較慢。因此,如果您的收藏中有很多條目,那就HashSet<T>更好了。
我個人使用ICollection<T>普通屬性,只是因為它是一個眾所周知的介面,成本最小,即創建 anICollection比創建 a稍微快一點IList。你當然可以使用HashSet<T>EF Core 使用的,但我發現HashSet’s 比 ’s 更難設置ICollection<T>,後者需要List<T>.
HashSet<T>如果您使用未初始化的支持欄位集合,則必須使用的一個地方- 請參見下面的程式碼:private HashSet<Review> _reviews; public IEnumerable<Review> Reviews => _reviews?.ToList();更新:使用 EF Core 3,必須使用
HashSet<T>未初始化集合的限制已被刪除(請參閱此問題)。您可以使用ICollection<T>等List<T>。
IEnumerable<T>``IEnumerable是一種特殊情況,因為它沒有AddorRemove方法,將集合變成只讀版本。支持欄位加上IEnumerable<T>(請參閱上面的程式碼)允許您“鎖定”集合關係,以便只能從類內部更改它(請參閱我的文章EF Core 中的域驅動設計)。當我使用支持欄位集合時,我讓它們未初始化,所以它們需要是
HashSet<T>. 這允許我檢測我何時忘記使用 .Include 載入實體時,例如,如果我載入一本書而沒有.Include(p => p.Reviews)然後訪問評論屬性,我會得到一個空引用異常。這只是一種安全的程式方式。如果您初始化支持欄位集合,那麼它可以是
ICollection等等,但我不建議初始化支持欄位集合,因為如果您忘記包含然後將項目添加到集合中,它可能會導致問題。在這種情況下,EF Core 會刪除任何現有的評論並將其替換為您添加的新評論。從 EF Core 的角度來看,它按照您所說的做,但很可能不是您想要的。
