EF的 NoTracking 的一些記錄
NoTracking官方解釋
跟蹤與非跟蹤查詢
跟蹤行為可控制 Entity Framework Core 是否將有關實體實例的信息保留在其更改跟蹤器中。 如果已跟蹤某個實體,則該實體中檢測到的任何更改都會在
SaveChanges()期間永久保存到數據庫。Entity Framework Core 還會修正從跟蹤查詢中獲取的實體與先前已加載到 DbContext 實例中的實體兩者之間的導航屬性。
可以理解為:
DbContext如果配置為TrackAll。
則DbContext會跟蹤返回的實體實例,記錄增刪改查的跟蹤記錄,并自動整合變化,推送Diff Change保留至數據庫。
DbContext如果配置為NoTracking。
則DBContext不會跟蹤實體變化(不再自動標記實體變化,但手動標記仍有效),并不自動修正變化。
1.對增刪改查的影響
NoTracking 不允許 相同的實體被標記多次

也就是 Attach 的實體必須有不同的標記。
但TrackAll不會有此問題,因為會自動修正2個實體標記
2.查詢緩存
public void Test() { var id = st.T_User.Select(o => o.ID).FirstOrDefault(); using (FLFPermissionEntities ent = dbr.CreateContext<FLFPermissionEntities>()) { using (FLFPermissionEntities sub1 = new FLFPermissionEntities()) { var jm = sub1.FlexUpdate<T_User>(o => o.Name = "lcc", o => o.ID == id); if (jm.HasMsg()) Assert.Fail(jm.msg); } var user21 = ent.T_User.FirstOrDefault(o => o.ID == id); Console.WriteLine($"TrackAllDBContext 第一次讀取:{user21.Name}"); using (FLFPermissionEntities sub2 = new FLFPermissionEntities()) { Console.WriteLine($"改變Name的值為lcc2"); var jm = sub2.FlexUpdate<T_User>(o => o.Name = "lcc2", o => o.ID == id); if (jm.HasMsg()) Assert.Fail(jm.msg); } var user22 = ent.T_User.FirstOrDefault(o => o.ID == id); Console.WriteLine($"TrackAllDBContext 第二次讀取:{user22.Name}"); } using (FLFPermissionEntities ent = dbr.CreateReadContext<FLFPermissionEntities>()) { using (FLFPermissionEntities sub1 = new FLFPermissionEntities()) { var jm = sub1.FlexUpdate<T_User>(o => o.Name = "lcc", o => o.ID == id); if (jm.HasMsg()) Assert.Fail(jm.msg); } var user21 = ent.T_User.FirstOrDefault(o => o.ID == id); Console.WriteLine($"NoTrackDBContext 第一次讀取:{user21.Name}"); using (FLFPermissionEntities sub2 = new FLFPermissionEntities()) { Console.WriteLine($"改變Name的值為lcc2"); var jm = sub2.FlexUpdate<T_User>(o => o.Name = "lcc2", o => o.ID == id); if (jm.HasMsg()) Assert.Fail(jm.msg); } var user22 = ent.T_User.FirstOrDefault(o => o.ID == id); Console.WriteLine($"NoTrackDBContext 第二次讀取:{user22.Name}"); } }

NoTrack的結果是正確的,TrackAll的結果與實際結果不同
會發現 TrackAll的 2次查詢 結果是一樣的,而且TrackAll的第二次讀取時已經訪問了數據,但出來的結果 還是lcc 并不是lcc2。
所以TrackAll 會從數據庫讀取數據后,根據跟蹤記錄里的數據信息,覆蓋數據庫中讀取的結果
DbContext 認為 跟蹤記錄的數據必須統一且數據已跟蹤記錄為準

浙公網安備 33010602011771號