1 回答

TA貢獻1829條經(jīng)驗 獲得超7個贊
對我來說,實體框架加載所有孩子只是為了添加一個真的沒有意義
延遲加載發(fā)生在您第一次通過其getter訪問導(dǎo)航屬性時。以及示例代碼
_parent.Children.Add(child);
由兩個操作組成:
(1)檢索Children屬性(通過屬性getter!):
var children = _parent.Children;
(2)對其進行一些操作(Add本例中調(diào)用方法):
children.Add(child);
延遲加載是由于操作 (1) 而發(fā)生的。如您所見,EF 與此無關(guān),因為它無法控制它。并且沒有辦法知道您將如何處理該屬性值 - 枚舉它,進行計數(shù)或使用Add等Remove方法。
這里有一些解決方案。
首先,為什么要使用延遲加載?它有很多副作用和低效率,所有這些都可以通過 EF 提供的開箱即用的急切加載Include方法輕松解決。這就是為什么默認情況下 EF Core(“EF 的未來”)默認情況下不使用延遲加載,并且需要一個特殊的包和過程來啟用它。
其次,如果你堅持使用延遲加載,那么你有以下兩種選擇:
(A) 在數(shù)據(jù)修改期間禁用延遲加載(需要訪問/控制DbContext實例):
dbContext.Configuration.LazyLoadingEnabled = false;
_parent.Children.Add(child);
dbContext.Configuration.LazyLoadingEnabled = true;
這也需要初始化集合屬性以避免 NRE。
(B) 使用顯式支持字段并提供對其的直接訪問(以避免觸發(fā)屬性訪問器的延遲加載)。例如:
public class Parent
{
public Guid Id { get; set; }
private ICollection<Child> children;
public virtual ICollection<Child> Children { get => children; set => children = value; }
public void Add(Child child)
{
// use the backing field directly
if (children == null) children = new HashSet<Child>();
children.Add(child);
}
}
- 1 回答
- 0 關(guān)注
- 122 瀏覽
添加回答
舉報