1. 程式人生 > >EF Core 三 、 EF Core CRUD

EF Core 三 、 EF Core CRUD

# EF Core CRUD 上篇文章中,我們已經基本入門了EFCore,搭建了一個簡單的EFCore專案,本文開始簡單使用下EF,做增刪改查的相關操作; ## 一、資料新增操作(C) ``` C# public static async void Insert_測試新增資料1() { var myDbContext = new MyDbContext(); if (myDbContext.TestTables.Any(p => p.Id == 1)) return; var newEntity = new TestTable { Id = 1, Name = "主表資料1" }; await myDbContext.TestTables.AddAsync(newEntity); myDbContext.SaveChanges(); Console.WriteLine($"TestTable Insert Success"); Console.WriteLine($"------------------------"); } ``` 是不是很簡單的程式碼?so eays ... 我們還是來分析下整體程式碼的執行; **1.首先我們自己在程式碼段中新增了一個實體物件,並對其欄位做賦值,然後通過Add方法加入到DbSet中 2.通過DbContext.SaveChanges提交資料到資料庫儲存** 那EF是如何偷偷的在背後幫我們完成這一切的呢? **EFCore實體四狀態,** 如下四種狀態; ``` C# public enum EntityState { /// /// The entity is not being tracked by the context. /// Detached = 0, /// /// The entity is being tracked by the context and exists in the database. Its property /// values have not changed from the values in the database. /// Unchanged = 1, /// /// The entity is being tracked by the context and exists in the database. It has been marked /// for deletion from the database. ///
Deleted = 2, /// /// The entity is being tracked by the context and exists in the database. Some or all of its /// property values have been modified. /// Modified = 3, /// /// The entity is being tracked by the context but does not yet exist in the database. ///
Added = 4 } ``` Detached : 實體未被跟蹤 Unchanged:未修改 Deleted : 刪除狀態 Modified:修改狀態 Added:新增狀態 Detached 未被跟蹤狀態,很多同學可能無法理解了,EFCore會預設自動跟蹤實體資訊,用來維護實體狀態,也是方便後續提交時的處理;EFCore提供兩種查詢方法,跟蹤查/非跟蹤查,跟蹤查得到的資料是Unchanged,而非跟蹤查的到的資料是Detached,這兩種方式我們後面詳細說明,這裡先簡單描述下; **EFCore管理記憶體實體** 檢視DbContext原始碼中的Add方法,跟蹤方法,發現Add方法會呼叫到 EntityReferenceMap.cs 類中的Update方法 (下面的原始碼內容),此方法中EFCore會在記憶體中維護我們操作的實體資訊,將我們操作的實體資訊管理到記憶體中(我們的增刪改查操作,EFCore都會再記憶體維護,方法中只是對實體狀態維護,SaveChanges才會提交); ``` C# public virtual void Update( [NotNull] InternalEntityEntry entry, EntityState state, EntityState? oldState) { var mapKey = entry.Entity ?? entry; var entityType = entry.EntityType; if (_hasSubMap && entityType.HasDefiningNavigation()) { if (_dependentTypeReferenceMap == null) { _dependentTypeReferenceMap = new Di