Dapper使用技巧
Dapper介紹
Dapper是輕量級(jí)的.net ORM框架,配合linq和泛型,讓C#操作數(shù)據(jù)的代碼簡(jiǎn)潔、高效又靈活!最近的工作項(xiàng)目中使用了Dapper,在這里分享一些實(shí)用技巧。閱讀之前需要了解一些基本的使用方法,參見(jiàn)官網(wǎng)http://dapper-tutorial.net/ 。
?
Dapper撤銷(xiāo)查詢(xún)
你的應(yīng)用程序應(yīng)該給用戶(hù)提供各種“取消”的功能,這就在包括了查詢(xún)數(shù)據(jù)的時(shí)候撤銷(xiāo)一條正在執(zhí)行的查詢(xún),Dapper像很多ORM一樣提供了這個(gè)操作,看看這段代碼:// using Dapper;
var products = sqlConnection.QueryAsync<Product>(new CommandDefinition(
queryProducts,
new { Type = "SomeType" },
commandTimeout: 60,
cancellationToken: myToken)).Result.ToList();
?
?
這里Product是定義好的數(shù)據(jù)類(lèi),queryProducts是查詢(xún)文本,myToken是定義好的Task的CancellationToken。這段代碼使用QueryAsync異步方法實(shí)現(xiàn)了可撤銷(xiāo)的查詢(xún)操作,開(kāi)發(fā)者需要把控制撤銷(xiāo)的myToken傳給CommandDefinition的可選參數(shù)cancellationToken。使用代碼之前,要了解一下C#的Task概念。
另外值得注意的是,查詢(xún)的TimeOut可以通過(guò)commandTimeout設(shè)置(默認(rèn)30s)。
?
Dapper使用事務(wù)
事務(wù)是數(shù)據(jù)庫(kù)的重要概念,Dapper對(duì)事務(wù)提供了很好的支持,看看這段代碼:
?
1 // using System.Linq; 2 // using System.Data.SqlClient; 3 using (SqlTransaction tran = sqlConn.BeginTransaction()) 4 { 5 var pars = ProductsWithNewPrice.Select(t => { return new { t.ProductID, t.Price }; }); 6 sqlConn.Execute(UpdateProductPrice, pars, transaction: tran); 7 tran.Commit(); 8 }?
通過(guò)喜聞樂(lè)見(jiàn)的using形式執(zhí)行一段事務(wù),這里假設(shè)ProductsWithNewPrice是一個(gè)具有新價(jià)格的Product類(lèi)的集合,事務(wù)的目的是把這些新價(jià)格通過(guò)Update語(yǔ)句更新到數(shù)據(jù)庫(kù)中。第5行用linq取出了具有ProductID和Price字段的臨時(shí)類(lèi)型的集合,這個(gè)集合作為下面一行所執(zhí)行的sql語(yǔ)句們的參數(shù)。UpdateProductPrice是查詢(xún)文本,應(yīng)該是類(lèi)似這樣的“UPDATE dbo.Product set Price = @Price WHERE ProductID = @ProductID;”。因?yàn)槭褂昧藅ransaction,pars集合中的所有參數(shù)對(duì)應(yīng)的"UPDATE"語(yǔ)句會(huì)在同一個(gè)事務(wù)中完成。
?
從數(shù)據(jù)庫(kù)取UTC時(shí)間
我們假設(shè)工作環(huán)境中數(shù)據(jù)庫(kù)一直使用UTC時(shí)間(現(xiàn)實(shí)經(jīng)常是這樣),我們寫(xiě)的代碼經(jīng)常從數(shù)據(jù)庫(kù)中讀取時(shí)間并轉(zhuǎn)化成C#的DateTime結(jié)構(gòu)。轉(zhuǎn)化的時(shí)候Datretime.Kind屬性經(jīng)常被忽略,這可能導(dǎo)致隨后的使用中把時(shí)間值當(dāng)做本地時(shí)間。要確保避免這樣的錯(cuò)誤,我們可以做一個(gè)設(shè)定,把Dapper取到的值指定DateTimeKind為UTC,并把正確的UTC時(shí)間存儲(chǔ)到數(shù)據(jù)庫(kù)。代碼是這樣的,先創(chuàng)建DateTimeHandler類(lèi):
?
public class DateTimeHandler : SqlMapper.TypeHandler<DateTime>{public override void SetValue(IDbDataParameter parameter, DateTime value){parameter.Value = DateTime.SpecifyKind(value, DateTimeKind.Utc);}public override DateTime Parse(object value){return DateTime.SpecifyKind(Convert.ToDateTime(value), DateTimeKind.Utc);}}?
然后在你的類(lèi)的構(gòu)造函數(shù)中加入這行:
SqlMapper.AddTypeHandler(new DateTimeHandler());這樣,Dapper取到的時(shí)間值和通過(guò)Dapper保存到數(shù)據(jù)庫(kù)的時(shí)間值就都是UTC時(shí)間了。
?
使用字符串變量名拼接多個(gè)SQL語(yǔ)句
請(qǐng)看下面這段代碼。這里使用加號(hào)“+”拼接了兩個(gè)不同功能的SQL語(yǔ)句,并且讓兩個(gè)語(yǔ)句都可以復(fù)用!我認(rèn)為這在指定情景中是一個(gè)很好的實(shí)踐。
var nextWorkID = sqlConn.Query<int>(SubmitCurrentWork + FindNextWorkID, new { currentWorkID, currentWorkResult }).FirstOrDefault();不過(guò)這樣使用Dapper有兩個(gè)要求:
滿(mǎn)足了這兩個(gè)要求才能寫(xiě)上面那樣的代碼。上面代碼中的SQL字符串變量可以是下面這樣:
string SubmitCurrentWork = "UPDATE dbo.Works SET WorkResult = @currentWorkResult, Status = 'Done' WHERE ID = @currentWorkID;";string FindNextWorkID = "SELECT TOP 1 ID FROM dbo.Works WHERE Status != 'Done';"; // 如果這里有名為@currentWorkResult或@currentWorkID的變量,其用途/含義要和上面的語(yǔ)句一致?
?
總結(jié)
以上是生活随笔為你收集整理的Dapper使用技巧的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 一家创业公司发展历程-真实记录
- 下一篇: FreeSql与SqlSugar性能测试