C# 數據操作系列 - 8. EF Core的增刪改查

C# 數據操作系列 - 8. EF Core的增刪改查

0.前言
到目前爲止,我們看了一下如何聲明EF Core的初步使用,也整體的看了下EF Core的映射關係配置以及導航屬性的配置。

這一篇,我帶大家分享一下,我在工作中需要的EF Core的用法。

  1. 初始化
    在實際開發中,一般都是先設計好數據表再進行開發,所以很少用到EF Core的數據遷移功能。所以EF Core的初始化,一般也指的是EF Core上下文初始化。

1.1 連接字符串
我們通過前面的文章知道,EF Core在上下文初始化的時候,都需要一個鏈接字符串。如果在不考慮後續變更或者上下文的複用性,可以直接在自定義Context裏重寫OnConfiguring方法中定義。

如果需要後續變更,那麼就需要在創建自定義EF Core 上下文類的時候,爲之添加一個連接字符串的屬性或者字段,以方便初始化的時候指定。實例:

public class DefaultContext : DbContext
{

private string Connection { get; set; } = "Data Source=./blogging1.db";
public DefaultContext(string connection)
{
    Connection = connection;
}
protected override void OnConfiguring(DbContextOptionsBuilder options)
    => options.UseSqlite(Connection);

}
這樣一來,我們在後續使用的時候,就可以指定連接字符串了。當然了,如果有小夥伴有更好的方法也可以分享出來呀。

1.2 配置文件的加載或者實體對象的託管
如果我們不使用配置文件的話,就必須在EF Core的上下文類裏添加一個類型是DbSet的屬性。繼續延續上面的實例:

public class SingleModel
{

public int Id { get; set; }
public int TargetId { get; set; }
public SingleTargetModel SingleTarget { get; set; }

}

public class SingleTargetModel
{

public int Id { get; set; }
public SingleModel Single { get; set; }

}
public class DefaultContext : DbContext
{

// 其餘代碼參見 1.1  DefaultContext
public DbSet<SingleModel> Singles { get; set; }
public DbSet<SingleTargetModel> Targets { get; set; }

}
以上也就是這一小節標題中的實體對象的託管。我沒找到EF Core官方文檔中對於這種方式的稱呼,所以我就悄悄的搶注了一下爲託管。

如果我們使用Config類(也就是 《C# 數據操作系列 - 7. EF Core 導航屬性配置》中介紹的配置類)的話,需要在EF Core中應用配置,具體是:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{

modelBuilder.ApplyConfiguration(new SingleModelConfig());
modelBuilder.ApplyConfiguration(new SingleTargeModelConfig());

}
在使用的時候,可以直接:

var context = new DefaultContext("Data Source=demo.db");
var t1 = context.Set().First();
即使用DbContext.Set,可以獲取到一個數據加載集,當然也可以結合實體類的託管來一起使用。

那麼爲什麼,我推薦使用配置類加載嗎?

因爲在實際開發中,一個完整的程序或者網站實體類都會大於10,而這些如果使用屬性的形式會非常多,不利於實際開發。而且,EF Core可以通過 Assembly 方式整體加載配置文件。再者,爲了保證ORM中的O不受其他因素的影響。也就是說,如果使用註解形式配置映射關係,那麼勢必會造成影響。

當然了,使用配置文件必然會導致項目的類增多,而且大量的重複類可能會出現。當然了,如果考慮到這個問題的話,可以試試寫一個項目代碼生成器哦,專門用來處理這些差不多的類。

咳咳,總而言之,使用配置文件利大於弊,所以我推薦使用配置文件對關係進行配置。

  1. 數據變化
    換句話說,嗯,也就是增刪改。在數據增刪這兩方面,EF Core沒有太多需要注意的地方。不過如果有導航屬性的話,在新增的時候,EF Core會自動檢索導航屬性的另一端是否需要新增到數據庫中,如果需要新增的話,EF Core會自動標記爲新增的。

而刪除,如果在配置導航屬性時,沒有設置級聯刪除,刪除當前元素,如果另一端的外鍵是可空類型的,並不會刪除導航屬性另一端的元素只會設置外鍵指向爲NULL,如果另一端外鍵是不可空的,那麼就會同時刪除。如果需要修改,可以使用以下方法修改,在配置導航屬性的時候:

OnDelete(DeleteBehavior.Cascade);
對於可爲NULL的外鍵來說,枚舉DeleteBehavior的值起以下作用:

行爲名稱 對內存中的依賴項/子項的影響 對數據庫中的依賴項/子項的影響
Cascade 刪除實體 刪除實體
ClientSetNull(默認) 外鍵屬性設置爲 null None
SetNull 外鍵屬性設置爲 null 外鍵屬性設置爲 null
Restrict None None
而對於不可爲NULL的外鍵來說,枚舉DeleteBehavior的值起以下作用:

行爲名稱 對內存中的依賴項/子項的影響 對數據庫中的依賴項/子項的影響
Cascade(默認) 刪除實體 刪除實體
ClientSetNull SaveChanges 引發異常 None
SetNull 引發 SaveChanges SaveChanges 引發異常
Restrict None None
而對於數據的修改,EF Core的做法是通過監控實體的ChangeTracker來實現對數據實體的狀態更新。也就是說,如果你從EF Core的上下文獲取了一個實體對象,對這個對象的某些值進行了修改。這時候EF Core其實已經記錄了這個對象的修改。不需要我們額外的調用修改方法(因爲根本沒有Update方法)。

EF Core在我們調用 SaveChanges 會把緩存的所有更改(增、刪、改)都推送給數據庫。如果有一條數據變更因爲數據庫校驗或者其他約束沒有通過,就會報錯,同時撤銷所有已推送的變更並取消後續變更的推送。

從數據庫的角度來看,EF Core在SaveChanges的過程中是以事務的形式推送給數據庫的。如果出錯,那麼事務就會回滾。

所以一般情況下,EF不需要開啓事務。

3.花樣查詢
EF Core 支持Linq查詢,所以在查詢的時候可以使用Linq進行。簡單示例如下:

var context = new DefaultContext("Data Source=demo.db");
var results = from t in context.Set()

         select t;

當然,也可以使用方法鏈的形式傳入一個Expression> 類型的表達式。

var results = context.Set().Where(t=>true);
看到這裏了,可能會有疑問了,這明明很簡單呀。是的,如果只是查詢,自然簡單。

那麼,結合排序、分頁之後呢?先來看看排序是怎麼實現的吧。

在查詢表達式寫法中,排序應該這樣的寫的:

var results = from t in context.Set()

        orderby t.Id //descending 如果降序則取消註釋
        select t ;

方法鏈的形式是:

var results = context.Set().Where(t=>true).OrderBy(t=>t.Id);
分頁只能通過方法鏈的形式進行分頁,這裏提供一個分頁的工具方法:

public static IQueryable Paging(IQueryable source,int pageIndex,int pageSize)
{

return source.Skip(pageSize * (pageIndex - 1)).Take(pageSize);

}
這裏用到的是 Skip(int count) 表示忽略數據集的前count條記錄,Take(int count)取得數據集的前count條記錄。

EF Core在調用 ToList的時候,會將已調用的方法和Linq轉換成SQL語句,並正式向數據庫發起查詢。如果出現了在Linq中調用三方方法或者自己寫的工具方法的話,可能會提示不受支持。

如果使用的Linq表達式,則沒關係,EF Core在遇到這種情況的時候,會把數據庫裏所有數據都加載到上下文中,再執行後續的查詢等操作。

所以,爲了高效的查詢,在執行查詢的時候,最好使用簡單的查詢條件。

  1. 後續
    EF Core整體使用已經介紹完了,當然照例是普通工程級的內容。下一篇我給大家介紹一下EF Core剩下一些邊角料,嗯。如果要深挖代碼的話,得以後有機會了。

數據訪問系列,EF Core 篇即將到一段落。待EF Core篇完成後,將帶領一起去探索 Nhibernate和Dapper,SqlSugar這三個ORM框架。

原文地址https://www.cnblogs.com/c7jie/p/12910627.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章