EF Core 三 、 EF Core CRUD
阿新 • • 發佈:2020-11-23
# 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