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<T>的屬性,繼續延續上面的實體:
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<SingleTargetModel>().First();
即使用DbContext.Set<T>,可以獲取到一個資料加載集,當然也可以結合物體類的托管來一起使用,
那么為什么,我推薦使用配置類加載嗎?
因為在實際開發中,一個完整的程式或者網站物體類都會大于10,而這些如果使用屬性的形式會非常多,不利于實際開發,而且,EF Core可以通過 Assembly 方式整體加載組態檔,再者,為了保證ORM中的O不受其他因素的影響,也就是說,如果使用注解形式配置映射關系,那么勢必會造成影響,
當然了,使用組態檔必然會導致專案的類增多,而且大量的重復類可能會出現,當然了,如果考慮到這個問題的話,可以試試寫一個專案代碼生成器哦,專門用來處理這些差不多的類,
咳咳,總而言之,使用組態檔利大于弊,所以我推薦使用組態檔對關系進行配置,
2. 資料變化
換句話說,嗯,也就是增刪改,在資料增刪這兩方面,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<SingleTargetModel>()
select t;
當然,也可以使用方法鏈的形式傳入一個Expression<Func<T,bool>> 型別的運算式,
var results = context.Set<SingleTargetModel>().Where(t=>true);
看到這里了,可能會有疑問了,這明明很簡單呀,是的,如果只是查詢,自然簡單,
那么,結合排序、分頁之后呢?先來看看排序是怎么實作的吧,
在查詢運算式寫法中,排序應該這樣的寫的:
var results = from t in context.Set<SingleTargetModel>()
orderby t.Id //descending 如果降序則取消注釋
select t ;
方法鏈的形式是:
var results = context.Set<SingleTargetModel>().Where(t=>true).OrderBy(t=>t.Id);
分頁只能通過方法鏈的形式進行分頁,這里提供一個分頁的工具方法:
public static IQueryable<T> Paging<T>(IQueryable<T> 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在遇到這種情況的時候,會把資料庫里所有資料都加載到背景關系中,再執行后續的查詢等操作,
所以,為了高效的查詢,在執行查詢的時候,最好使用簡單的查詢條件,
4. 后續
EF Core整體使用已經介紹完了,當然照例是普通工程級的內容,下一篇我給大家介紹一下EF Core剩下一些邊角料,嗯,如果要深挖代碼的話,得以后有機會了,
資料訪問系列,EF Core 篇即將到一段落,待EF Core篇完成后,將帶領一起去探索 Nhibernate和Dapper,SqlSugar這三個ORM框架,
更多內容煩請關注我的博客《高先生小屋》

轉載請註明出處,本文鏈接:https://www.uj5u.com/net/36069.html
標籤:C#
下一篇:[原創][開源]SunnyUI.Net, C# .Net WinForm開源控制元件庫、工具類別庫、擴展類別庫、多頁面開發框架
