C# 資料操作系列 - 9. EF Core 完結篇

月影西下發表於2020-05-19

0.前言

《EF Core》實際上已經可以告一段落了,但是感覺還有一點點意猶未盡。所以決定分享一下,個人在實際開發中使用EF Core的一些經驗和使用的擴充套件包。

1. EF Core的非同步操作

正如這小節題目所言,EF Core是支援非同步操作的,但實際可用集中在SaveChanges和非同步查詢這兩個方法上。

具體方法宣告如下:

public virtual System.Threading.Tasks.Task<int> SaveChangesAsync (System.Threading.CancellationToken cancellationToken = null);
public virtual System.Threading.Tasks.Task<TEntity> FindAsync<TEntity> (params object[] keyValues) where TEntity : class;
public virtual System.Threading.Tasks.Task<TEntity> FindAsync<TEntity> (object[] keyValues, System.Threading.CancellationToken cancellationToken) where TEntity : class;
public virtual System.Threading.Tasks.Task<object> FindAsync (Type entityType, params object[] keyValues);
public virtual System.Threading.Tasks.Task<object> FindAsync (Type entityType, object[] keyValues, System.Threading.CancellationToken cancellationToken);

這五個方法分別是SaveChanges的非同步版,和Find的非同步版。兩種方法都支援傳入一個取消令牌(這部分內容需要等後期的《C# 非同步程式設計系列》裡介紹)。

返回一個Task,然後按照Task進行執行就行。

DbContext 也提供了Add/AddRange的非同步方法,但是這組方法的非同步版需要資料庫的支援,並不是一個通用的方法,所以就沒有提。

var context = new DefaultContext("Data Source=./blogging1.db");
var task1 = context.FindAsync<SingleModel>(1);
var result = task1.Result;
var task2 = context.SaveChangesAsync();

這兩個任務是建立一個熱啟動任務,也就是不用手動呼叫 Run方法。

回到資料查詢來,查詢的非同步支援方法組是來自於Linq,但是底層來源於資料訪問介面。

簡單的例項:

var task3 = context.Set<SingleModel>().Where(t => true).ToListAsync();

當獲取task3結果的時候,會強制等待任務完成執行。

2. using的另一種用法

我們知道using關鍵字通常用來引入名稱空間,當然微軟引入了另外一種用法。對於EF Core的DbContext,框架推薦在用完之後將上下文銷燬。而我們每次使用必須都進行手動銷燬。

如果我們在使用try/catch/finally進行捕獲異常的時候,需要在finally裡放資源釋放的程式碼。如果資源得不到正確及時的釋放會出現更多的問題。

為了改善這種現狀,微軟便新增了using關鍵字的另外一種用法。

using (var context = new DefaultContext("Data Source=./blogging1.db"))
{
    // 使用 context
}

以上例項程式碼中using的含義是宣告一個context作用於兩個大括號之間,當兩個大括號之間的程式碼執行完成後,會自動呼叫context.Dispose()方法。

using關鍵字的機制不會因為中途返回而不執行 context.Dispose(),也不會因為中間被丟擲異常不執行。using的使用並不侷限於實現IDisposable介面的物件,其他的物件也可以使用。

3. EF Core的資料庫訪問外掛

微軟為SQLite和SQL Server提供了預設的資料庫連線程式,其中 SQLite的是:

Microsoft.EntityFrameworkCore.Sqlite

SQL Server是:

Microsoft.EntityFrameworkCore.SqlServer

其他的常用資料庫都是由三方提供,以下是一些常見的連線程式包和資料庫名稱:

NuGet 程式包 支援的資料庫引擎 維護商/供應商
Npgsql.EntityFrameworkCore.PostgreSQL postgresql Npgsql 開發團隊
Pomelo.EntityFrameworkCore.MySql MySQL、MariaDB Pomelo Foundation 專案
Devart.Data.MySql.EFCore MySQL 5 及以上版本 DevArt
Devart.Data.Oracle.EFCore Oracle DB 9.2.0.4 及更高版本 DevArt
Devart.Data.PostgreSql.EFCore PostgreSQL 8.0 及以上版本 DevArt
Oracle.EntityFrameworkCore Oracle DB 11.2 及更高版本 Oracle

4. EF Core的配件

在EF 4的年代,EF本身不支援對批量資料的支援。後續慢慢增加了對陣列的處理,包括增刪。

但是隨著時代的發展,資料量越來越大。所以僅僅是陣列不能滿足實際需求了。

現在給大家推薦一個外掛:

Z.EntityFramework.Plus.EFCore

這個外掛可以擴充套件DbContext的功能,使其支援對查詢結果的操作:

var ctx = new DbContext();
var date = DateTime.Now.AddYears(-2);
ctx.Users.Where(x => x.LastLoginDate < date)
         .Delete();

// DELETE using a BatchSize
var date = DateTime.Now.AddYears(-2);
ctx.Users.Where(x => x.LastLoginDate < date)
         .Delete(x => x.BatchSize = 1000);

當然,還有更多的特點,以後在ASP.NET Core篇再為大家介紹。

5.後續

EF Core到目前為止已經結束了,下一篇將開始探索一下Nhibernate或者Dapper吧。OK,C#的資料訪問篇裡的大頭基本完成了。

下一個系列,小夥伴們打算看什麼?預計是開始ASP.NET Core 系列了。

更多內容煩請關注我的部落格《高先生小屋》

file

相關文章