怎麼處理資料庫溝通
相信這點是每個程式開發工程師關注的點,在dotnetcore中可以選擇EntityFramework或是用ADO.NET來處理資料庫問題,不過今天要介紹的是羽量級的套件Dapper,請大家繼續看下去。
如何處理資料庫溝通
「前輩,我要開始搞資料庫了,我該從哪裡著手」
一早大頭又有需求上的問題,今天似乎是跟資料庫相關的問題,由於小光也曾經有類似的問題,所以也想暸解該如何處理。
「那你有什麼需求呢?」
老K聽到大頭的問題之後反問他這個問題,這時大頭歪了頭想了一下,就這麼說。
「我想要寫一個處理速度快又可以簡單寫的」
聽到這回答後換老K思考了幾分鐘後這麼說。
「那你跟小光去研究一下Dapper」
Dapper
Dapper是一個針對關聯是資料表來處理效能優化的套件,而且使用上也不像ADO.NET要經過繁瑣的動作才可以解析資料庫的資料,而且使用上相當簡單,不過在進入教學前先來看一下環境設定的部分。
環境設定
首先要安裝的套件如下列命令列。
dotnet add package Dapper
dotnet add package System.Data.SqlClient
這邊說明一下,上面是安裝Dapper而下面安裝的是MsSql的連接程式,所以之後先說明如何跟MsSql連線。
連線處理
這邊我們是透過DbProviderFactories
來取得對應的連線工具,以目前例子來說對於MsSql就是要指定System.Data.SqlClient
。
var providerFactory = DbProviderFactories.GetFactory(ProviderName);
var connection = providerFactory.CreateConnection();
if (connection != null)
{
connection.ConnectionString = connectionString;
}
return connection;
不過並不是這樣就可以了,我們必須在程式開始前先註冊才行,所以在Program.Main
執行以下動作。
DbProviderFactories.RegisterFactory("System.Data.SqlClient", System.Data.SqlClient.SqlClientFactory.Instance);
接下來要注意的是,使用連線串的語句時要用using把他包起來,簡單講就是做完查詢後要釋放掉,這樣MsSql的連線才會透過連線池的管理,詳細的資訊可以看一下這篇[SQL Connection Pooling 行為觀察]。
using (var connection = await GetConnection("連線串"))
{
var sql = @"SELECT GETUTCDATE()";
result = await connection.QueryFirstOrDefaultAsync<DateTime>(sql);
}
至於連線串的部分可以透過之前介紹的設定檔來取的即可。
執行語法
其上在上面的範例種已經看到執行語法了,只要熟悉Linq的語句應該就如何使用了,再來就是後贅詞有Async
指的就是非同步的方法,所以如果要等待完成的話前面要記的加上await
,最後泛型的部分就是要轉型成甚麼類別。
如果有需要傳入參數的話就透過以下方式來傳遞。
public class Dog
{
public int? Age { get; set; }
public Guid Id { get; set; }
public string Name { get; set; }
public float? Weight { get; set; }
public int IgnoredProperty { get { return 1; } }
}
var guid = Guid.NewGuid();
var dog = connection.Query<Dog>("select Age = @Age, Id = @Id", new { Age = (int?)null, Id = guid });
不過這邊要注意一下關於使用到指定長度的字串,Dapper的執行會影響執行計畫,詳細請看這篇Dapper 用起來很友善,但是預設的參數型別對執行計劃不太友善。,所以在輸入字串時要注意輸入的值跟資料庫定義的值一致,如下所示。
await connection.QueryFirstOrDefaultAsync<PlayInfo>(sql,
new
{
Name = new DbString { Value = name, Length = 32 }
}
簡單說明就是使用DbString
這類別即可,至於細部資訊請看前面那一篇。
欄位對應
當然類別的屬性名稱未必會跟資料庫的欄位相符,所以這邊可以透過以下方法來將屬性名稱對應到資料庫欄位,首先先安裝以下套件Dapper.FluentMap。
dotnet add package Dapper.FluentMap
接下來建立對應的類別。
public class ProductMap : EntityMap<Product>
{
public ProductMap()
{
// Map property 'Name' to column 'strName'.
Map(p => p.Name)
.ToColumn("strName");
// Ignore the 'LastModified' property when mapping.
Map(p => p.LastModified)
.Ignore();
}
}
如果這邊不在乎欄位大小寫的話可以用以下語法。
Map(p => p.Name).ToColumn("strName", caseSensitive: false)
建立好對應的類別後再將他註冊進去即可,註冊的方法要在Startup.ConfigureServices
加上以下語法即可。
FluentMapper.Initialize(cfg =>
{
cfg.AddMap(new ProductMap());
});
後記
今天跟小光還有大頭認識如何處理連線問題,已經如何使用Dapper來執行資料庫語法以及資料庫欄位跟類別屬性的對應問題,希望對大家在資料庫的處理可以快速開發。