0. 前言 在前一篇中我們講到了Dapper的應用,但是給我們的感覺Dapper不像個ORM更像一個IDbConnection的擴展。是的,沒錯。在實際開發中我們經常用Dapper作為對EF Core的補充。當然了Dapper並不僅僅只有這些,就讓我們通過這一篇文章去讓Dapper更像一個ORM吧。 ...
0. 前言
在前一篇中我們講到了Dapper的應用,但是給我們的感覺Dapper不像個ORM更像一個IDbConnection的擴展。是的,沒錯。在實際開發中我們經常用Dapper作為對EF Core的補充。當然了Dapper並不僅僅只有這些,就讓我們通過這一篇文章去讓Dapper更像一個ORM吧。
1. Dapper Contrib
Dapper Contrib 擴展了Dapper對於實體類的CRUD方法:
安裝方法:
命令行:
dotnet add package Dapper.Contrib
NuGet:
Install-Package Dapper.Contrib
使用:
using Dapper.Contrib.Extensions;
這個是一個使得Dapper功能更強大的擴展包,因為支持了CRUD,所以需要對實體類添加配置,該擴展包使用Attribute作為依據進行相關映射配置:
[Table("Model")]
public class Model
{
[Key]
[ExplicitKey]
public int Id{get;set;}
[Computed]
public int Count {get;set;}
[Write]
public String Name{get;set;}
}
這是所有的配置,Table用來聲明是一個表,必須指定表名,Key表示該屬性是資料庫主鍵,ExplicitKey表示這個屬性是資料庫中顯示設置的主鍵,Computed表示該欄位是一個計算欄位,Write表示該欄位可以設置值進去。需要註意的是: Key和ExplicitKey這兩個不能同時標註在一個屬性上。
那麼接下來,我們看看它擴展了哪些方法:
插入單個對象:
public static long Insert<T>(this IDbConnection connection, T entityToInsert, IDbTransaction transaction = null, int? commandTimeout = null) where T : class;
其中 transcation表示事務,如果指定事務,數據的提交將由事務控制,該方法會返回插入對象的主鍵(如果對象主鍵是數字類型)或者返回一個待插入列表中已插入的行數。
獲取單個對象:
public static T Get<T>(this IDbConnection connection, [Dynamic] dynamic id, IDbTransaction transaction = null, int? commandTimeout = null) where T : class;
通過傳入主鍵,獲取一個數據
獲取所有數據:
public static IEnumerable<T> GetAll<T>(this IDbConnection connection, IDbTransaction transaction = null, int? commandTimeout = null) where T : class;
更新數據:
Dapper Contrib 提供了一個用來更新的方法:
public static bool Update<T>(this IDbConnection connection, T entityToUpdate, IDbTransaction transaction = null, int? commandTimeout = null) where T : class;
這個方法比較有意思的是
var entity = connection.Get<Model>(1);
entity.Name = "測試1";
connection.Update(entity);
和
var models = connection.GetAll<Model>();
foreach(var m in models)
{
Console.WriteLine(m);
m.StringLength ++;
}
connection.Update(models.AsList());
都可以,並不會報錯。
不過需要註意的是,如果需要更新的實例沒有指定主鍵值(主減屬性沒有賦值),則不會有任何行發生更新。而且在更新的時候,會更新所有列,不會因為不賦值就不更新。
刪除方法有兩個:
public static bool Delete<T>(this IDbConnection connection, T entityToDelete, IDbTransaction transaction = null, int? commandTimeout = null) where T : class;
public static bool DeleteAll<T>(this IDbConnection connection, IDbTransaction transaction = null, int? commandTimeout = null) where T : class;
刪除也是傳入一個實體類,一樣也只是需要主鍵有值,如果沒有找到主鍵對應的數據,則不會有任何變化。Delete與Update一樣,如果傳入一個List集合也是可以的。
2. Dapper Transaction
這個包擴展了Dapper的事務處理能力。雖然是Dapper的擴展包,但是是給IConnection添加了一個擴展方法。使用示例如下:
dotnet add package Dapper.Transaction
老規矩,記得先把包加進來。
然後代碼是這樣的:
using Dapper.Transaction;
using(var connection = new SqliteConnection("Data Source=./demo.db"))
{
connection.Open();
var transcation = connection.BeginTransaction();
// 編寫業務代碼
transcation.Commit();
}
如果使用Dapper Transaction,需要先調用 connection.Open()來確保連接是開啟狀態。
transcation這個對象可以當做普通的DbTranscation對象,傳給Dapper的方法來使用,也可以當做一個開啟了事務的Dapper客戶端來使用。也就是說,Dapper對IDbConnection擴展的方法,在這個包對IDbTranscation也擴展了響應的方法:
3. Dapper Plus
這個插件是Dapper上用來處理巨量數據的插件,但這是個收費版的插件,不過每個月都有一定的試用期限。想試試的可以下一下:
dotnet add package Z.Dapper.Plus
使用:
using Z.Dapper.Plus;
這個插件在使用之前需要先配置實體類與資料庫之間的映射關係:
DapperPlusManager.Entity<Customer>().Table("Customers");
DapperPlusManager.Entity<Supplier>().Table("Suppliers").Identity(x => x.SupplierID);
該插件支持四組大批量處理方式:
- Bulk Insert
- Bulk Update
- Bulk Merge
- Bulk Delete
// STEP MAPPING
DapperPlusManager.Entity<Supplier>().Table("Suppliers").Identity(x => x.SupplierID);
DapperPlusManager.Entity<Product>().Table("Products").Identity(x => x.ProductID);
// STEP BULKINSERT
using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
connection.BulkInsert(suppliers).ThenForEach(x => x.Products.ForEach(y => y.SupplierID = x.SupplierID)).ThenBulkInsert(x => x.Products);
}
// STEP BULKUPDATE
using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
connection.BulkUpdate(suppliers, x => x.Products);
}
// STEP BULKMERGE
using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
connection.BulkMerge(suppliers).ThenForEach(x => x.Products.ForEach(y => y.SupplierID = x.SupplierID)).ThenBulkMerge(x => x.Products);
}
// STEP BULKDELETE
using (var connection = new SqlConnection(FiddleHelper.GetConnectionStringSqlServerW3Schools()))
{
connection.BulkDelete(suppliers.SelectMany(x => x.Products)).BulkDelete(suppliers);
}
4. 總結
這些插件讓Dapper更強,也更具備一個完整的ORM的方法,當然實際開發中需要結合實際需求使用。可能並不是所有的都合適。
Dapper的內容就到此為止了。本來預計下一篇開始 asp.net core的內容,不過有個小伙伴推薦了FreeSql,我看了下感覺挺不錯的,就給小伙伴們介紹一下~這一個介紹完成之後,就進入了我期待已久的asp.net core系列了。
更多內容煩請關註我的博客《高先生小屋》