[英]Entity Framework lazy loading with AsNoTracking()
我們目前正在為實體框架使用延遲加載並遇到out of memory exception
。 我們遇到這個異常的原因是因為 Linq 查詢加載了大量數據,並且在后期階段它使用延遲加載來加載導航屬性。 但是因為我們不使用NoTrackingChanges
實體框架緩存構建得非常快,這會導致內存不足錯誤。
我對 EF 的理解是,除非您想更新查詢中返回的對象,否則我們應該始終在查詢中使用NoTrackingChanges
。
然后我使用NoChangeTracking
進行了測試:
var account = _dbcontext.Account
.AsNoTracking()
.SingleOrDefault(m => m.id == 1);
var contactName = account.Contact.Name
但我收到以下錯誤:
System.InvalidOperationException:當返回帶有 NoTracking 合並選項的對象時,僅當 EntityCollection 或 EntityReference 不包含對象時才能調用 Load。
您已指定 EF 不跟蹤您的實例化Account
值:
var account = _dbcontext.Account.AsNoTracking().SingleOrDefault(m=>m.id == 1);
因此,嘗試訪問導航屬性將永遠不會奏效:
var contactName = account.Contact.Name
您可以使用Include()
顯式包含所需的導航屬性。 所以以下應該工作:
var account = _dbcontext.Account
.Include(a => a.Contact)
.AsNoTracking()
.SingleOrDefault(m=>m.id == 1);
var contactName = account.Contact.Name; // no exception, it's already loaded
我真的不相信使用 AsNoTracking 可以防止使用延遲加載
它可以非常快速地進行測試:
public static void Main()
{
var actor1 = new Actor { Id = 1, Name = "Vin Diesel" };
var movie1 = new Movie { Id = 1, Title = "Fast and Furious", PrimaryActor = actor1 };
using (var context = new MovieDb())
{
Console.WriteLine("========= Start Add: movie1 ==============");
context.Movies.Add(movie1);
context.SaveChanges();
Console.WriteLine("========= END Add: movie1 ==============");
var m1 = context.Movies.First();
Console.WriteLine(m1.PrimaryActor.Name);
var m2 = context.Movies.Include(m => m.PrimaryActor).AsNoTracking().First();
Console.WriteLine(m2.PrimaryActor.Name);
var m3 = context.Movies.AsNoTracking().First();
Console.WriteLine(m3.PrimaryActor.Name);
}
}
輸出:
======== 開始添加:movie1 ==============
========== 結束添加:movie1 ============
范·迪塞爾
范·迪塞爾
運行時異常(第 31 行):未將對象引用設置為對象的實例。
變量m1
由上下文跟蹤,因此它可以延遲加載導航屬性並打印值。 m2
沒有被跟蹤,但我已經明確地包含了導航屬性,所以它會打印值。 m3
沒有被跟蹤,我沒有明確包含它,因此該值為null
,我們得到了一個 NRE。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.