亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 學院 > 開發設計 > 正文

Dapper-.Net環境下一個簡單對象映射的框架

2019-11-14 16:05:51
字體:
來源:轉載
供稿:網友

本文內容

  • 特點
  • 性能
  • 參數化的查詢
  • List 支持
  • 緩存和非緩存的 readers
  • 多個映射
  • 多個結果
  • 存儲過程
  • Ansi Strings 和 varchar
  • 限制和注意事項
  • Dapper 能運行在我的 db 提供者上嗎?
  • 有例子的完整例子列表嗎?
  • 誰在使用 Dapper?
  • 參考

跳槽了,新公司的數據庫層,準確地說,數據庫層和持久層使用 Dapper,這東西的確很方便~個人覺得這種方便性體現在三點:

  1. 能很方便地執行數據庫 DML 和 DLL 操作。比如,當你執行一個帶參數的 SQL 時,SQL 中的變量能與你傳遞給它的實體或匿名對象中的屬性,自定匹配。而我們知道,帶參數的 SQL,能提高數據庫執行 SQL 的效率;
  2. 能很方便地將數據庫檢索結果映射為面向對象的對象。從數據庫中的檢索結果,通常是張二維表,如 DataTable,而應用程序中是實體類,以及實體類的集合,那么 Dapper 能夠將 DataTable 自動地映射成為實體類的集合;
  3. 能很方便地書寫 SQL 語句。比如,寫多個 SQL,用分號分隔。

下載 Demo

(該下載包含 Dapper 項目,項目中有 Dapper 的測試示例和性能測試例子)

(Dapper 的示例使用 SQLServer 數據庫,我個人的示例是 MySQL

特點


Dapper 只有一個文件,你可以把它拖到你的項目中,來擴展你的 IDbConnection 接口。

它提供了三方面的幫助:

執行一個查詢,并把結果映射到一個強類型 list

注意:所有的擴展方法都假設數據庫連接已打開,如果關閉連接,它們將失敗。

public static IEnumerable<T> Query<T>(this IDbConnection cnn, string sql, object param = null, SqlTransaction transaction = null, bool buffered = true)

用法:

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 });
 
dog.Count()
    .IsEqualTo(1);
 
dog.First().Age
    .IsNull();
 
dog.First().Id
    .IsEqualTo(guid);

執行一個查詢,并把結果映射到一個動態 object 的 list

public static IEnumerable<dynamic> Query (this IDbConnection cnn, string sql, object param = null, SqlTransaction transaction = null, bool buffered = true)

該方法將執行 SQL,并返回一個動態 list,即 var 變量。

用法:

var rows = connection.Query("select 1 A, 2 B union all select 3, 4");
 
((int)rows[0].A)
   .IsEqualTo(1);
 
((int)rows[0].B)
   .IsEqualTo(2);
 
((int)rows[1].A)
   .IsEqualTo(3);
 
((int)rows[1].B)
    .IsEqualTo(4);

rows[0] 這種訪問方式會出錯,不知道示例是怎么給的~

執行一個不返回結果的 Command

public static int Execute(this IDbConnection cnn, string sql, object param = null, SqlTransaction transaction = null)

用法:

connection.Execute(@"
  set nocount on 
  create table #t(i int) 
  set nocount off 
  insert #t 
  select @a a union all select @b 
  set nocount on 
  drop table #t", new {a=1, b=2 })
   .IsEqualTo(2);

多次執行一個 Command


相同的簽名也可以讓你方便高效地對一個命令執行多次,例如批量加載數據(bulk-load data)。

用法:

connection.Execute(@"insert MyTable(colA, colB) values (@a, @b)",
    new[] { new { a=1, b=1 }, new { a=2, b=2 }, new { a=3, b=3 } }
  ).IsEqualTo(3); // 3 rows inserted: "1,1", "2,2" and "3,3"

對任何類型實現 TIEnumerable 的參數都可以執行。

性能


Dapper 的主要特點是性能。以下數據顯示對一個數據庫執行 SELECT 出 500 條,并把數據映射到對象中需要多長時間。

性能測試分為三個方面:

  • POCO 序列化框架,支持從數據庫獲得靜態類型的對象。使用原始的 SQL。
  • 動態序列化框架,支持返回對象的動態列表。
  • 典型的框架用法。往往不會涉及編寫 SQL。

Performance of SELECT mapping over 500 iterations - POCO 序列化

方法

持續時間(毫秒)

備注

Hand coded (using a SqlDataReader)

47

Can be faster

Dapper ExecuteMapperQuery

49

同上

ServiceStack.OrmLite (QueryById)

50

同上

PetaPoco 

52

同上

BLToolkit

80

同上

SubSonic CodingHorror

107

同上

NHibernate SQL

104

同上

Linq 2 SQL ExecuteQuery

181

同上

Entity framework ExecuteStoreQuery

631

同上

Performance of SELECT mapping over 500 iterations - dynamic 序列化

方法

持續時間(毫秒)

備注

Dapper ExecuteMapperQuery (dynamic)

48

 

Massive

52

 

Simple.Data

95

 

Performance of SELECT mapping over 500 iterations - 典型用法

方法

持續時間(毫秒)

備注

Linq 2 SQL CompiledQuery

81

Not super typical involves complex code

NHibernate HQL

118

 

Linq 2 SQL

559

 

Entity framework

859

 

SubSonic ActiveRecord.SingleOrDefault

3619

 

參數化的查詢


參數可以作為匿名類來傳遞。這使你可以輕松地給命名參數,只要簡單地剪切和粘貼 SQL 片斷,并在查詢分析器中執行即可。

new {A = 1, B = "b"} // A will be mapped to the param @A, B to the param @B 

List 支持


Dapper 運行讓你傳遞 IEnumerable,自動地參數化的查詢。

例如下面 SQL 的 in 查詢:

connection.Query<int>("select * from (select 1 as Id union all select 2 union all select 3) as X where Id in @Ids", new { Ids = new int[] { 1, 2, 3 });

將被翻譯為:

select * from (select 1 as Id union all select 2 union all select 3) as X where Id in (@Ids1, @Ids2, @Ids3)" // @Ids1 = 1 , @Ids2 = 2 , @Ids2 = 3

緩存和非緩存的 readers


Dapper 的默認動作是執行 SQL 并在返回時緩沖整個 reader。在大多數情況下,這是理想的,因為它能最大限度地減少數據庫中的共享鎖,以及減少數據庫的網絡時間。

但是,在執行龐大查詢時,你可能為了減少內存的占用,只加載需要的對象。要做到這點,通過緩沖到查詢方法中。

/// <summary>
/// NonBuffered
/// 將會拋出異常,Invalid attempt to Read when reader is closed.
/// </summary>
public static void TestBasicStringUsageAsyncNonBuffered()
{
    var query = DbHelp.QueryAsync<string>(new CommandDefinition("select 'abc' as Value union all select @txt", new { txt = "def" }, flags: CommandFlags.None));
    var arr = query.Result.ToArray();
    arr.IsSequenceEqualTo(new[] { "abc", "def" });
}
 
/// <summary>
/// Buffered
/// 不會拋出異常
/// </summary>
public static void TestBasicStringUsageAsyncBuffered()
{
    var query = DbHelp.QueryAsync<string>(new CommandDefinition("select 'abc' as Value union all select @txt", new { txt = "def" }, flags: CommandFlags.Buffered));
    var arr = query.Result.ToArray();
    arr.IsSequenceEqualTo(new[] { "abc", "def" });
}
/// <summary>
/// Pipelined
/// 將會拋出異常,Invalid attempt to Read when reader is closed.
/// </summary>
public static void TestBasicStringUsageAsyncPipelined()
{
    var query = DbHelp.QueryAsync<string>(new CommandDefinition("select 'abc' as Value union all select @txt", new { txt = "def" }, flags: CommandFlags.Pipelined));
    var arr = query.Result.ToArray();
    arr.IsSequenceEqualTo(new[] { "abc", "def" });
}

多個映射


Dapper 允許你把單行映射到多個對象。如果你想避免額外的查詢和加載關聯,那么這個功能就很關鍵了。

例如:

var sql = 
@"select * from #Posts p 
left join #Users u on u.Id = p.OwnerId 
Order by p.Id";
 
var data = connection.Query<Post, User, Post>(sql, (post, user) => { post.Owner = user; return post;});
var post = data.First();
 
post.Content.IsEqualTo("Sams Post1");
post.Id.IsEqualTo(1);
post.Owner.Name.IsEqualTo("Sam");
post.Owner.Id.IsEqualTo(99);

提示:Dapper 假定你的 ID 列被命名為“ID”或“id”,如果你的主鍵是不同的,或者你想在點上拆分寬行點,而不是“ID”,可以使用可選的'splitOn'參數。

多個結果


Dapper 允許你在一次查詢中處理多個結果的集合。

例如:

var sql = 
@"
select * from Customers where CustomerId = @id
select * from Orders where CustomerId = @id
select * from Returns where CustomerId = @id";
 
using (var multi = connection.QueryMultiple(sql, new {id=selectedId}))
{
   var customer = multi.Read<Customer>().Single();
   var orders = multi.Read<Order>().ToList();
   var returns = multi.Read<Return>().ToList();
   ...
} 

存儲過程


Dapper 完全支持存儲過程:

var user = cnn.Query<User>("spGetUser", new {Id = 1}, 
        commandType: CommandType.StoredProcedure).First();}}}

如果你想要更靈活的操作,可以這樣做:

var p = new DynamicParameters();
p.Add("@a", 11);
p.Add("@b", dbType: DbType.Int32, direction: ParameterDirection.Output);
p.Add("@c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue);
 
cnn.Execute("spMagicProc", p, commandType: CommandType.StoredProcedure); 
 
int b = p.Get<int>("@b");
int c = p.Get<int>("@c"); 

Ansi Strings 和 varchar


Dapper 支持 varchar 參數,如果你在一個 varchar 列上執行一個 where 語句,確保下面方式傳遞參數:

Query<Thing>("select * from Thing where Name = @Name", new {Name = new DbString { Value = "abcde", IsFixedLength = true, Length = 10, IsAnsi = true });

在 SQL Server 上,當查詢非 Unicode 時,查詢 Unicode 和 ANSI 時需要使用 Unicode。

限制和注意事項


對于 Dapper 執行的每個查詢的緩存信息,使得它能夠快速地物化對象和處理參數。當前的實現把信息緩存在一個 ConcurrentDictionary 對象中。它存儲的對象永遠不會被刷新。如果你生成的 SQL 字符串沒有使用參數,那么可能會出現命中內存問題。我們把字典轉換成 LRU(Least Recently Used)緩存。

ORM 的很多特點都被 Dapper 去掉了,沒有身份地圖(Identity Map),沒有更新/選擇的助手等。

Dapper 不會管理你連接的生命周期,它假定它得到的連接是打開的,并且不存在 DataReader 枚舉(除非啟用 MARS)。

什么是 Mars?它是在創建數據庫連接時指定的,下面是 Dapper 中連接 SQL Server 的示例:

public static SqlConnection GetOpenConnection(bool mars = false)
{
    var cs = connectionString;
    if (mars)
    {
        SqlConnectionStringBuilder scsb = new SqlConnectionStringBuilder(cs);
        scsb.MultipleActiveResultSets = true;
        cs = scsb.ConnectionString;
    }
    var connection = new SqlConnection(cs);
    connection.Open();
    return connection;
}

如果指定了 Mars,那么還會創建 SqlConnectionStringBuilder,并指定其 MultipleActiveResultSets 屬性為 true。不過,看 Dapper 的例子,貌似 SQL Server 是有 Mars 的,但 MySQL 沒有。

Dapper 能運行在我的 db 提供者上嗎?


Dapper 能運行在所有 .net ado 提供者上,包括 sqlite,sqlce,firebird,Oracle,MySQL,PostgreSQL 和 SQL Server。

有例子的完整例子列表嗎?


Dapper 在測試項目中有完整的測試套件。

誰在使用 Dapper?


目前使用 Dapper 的有 Stack Overflow 和 helpdesk。

(if you would like to be listed here let me know)

參考資料


  • github Dapper
  • stackoverflow Dapper
  • A Look at Dapper.NET

 

下載 Demo


發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国产69精品99久久久久久宅男| 亚洲开心激情网| 欧美最猛性xxxx| 久久久久久久影院| 成人www视频在线观看| 色哟哟网站入口亚洲精品| www.日韩.com| 国产精品偷伦视频免费观看国产| 不卡av在线播放| 国产精品成人品| 久久久久久久久91| 成人a免费视频| 欧美极品少妇xxxxx| 日韩电影免费观看在线观看| 在线观看久久久久久| 欧美在线播放视频| 久久国产精品影片| 欧美日韩国内自拍| 日韩在线观看免费高清完整版| 欧美乱大交做爰xxxⅹ性3| 色综合天天狠天天透天天伊人| 黄色91在线观看| 福利二区91精品bt7086| 国产成人精品a视频一区www| 欧美性猛交xxxx黑人| 欧美电影免费观看电视剧大全| 136fldh精品导航福利| 欧美一区三区三区高中清蜜桃| 久久久综合av| 国产91网红主播在线观看| 亚洲电影在线观看| 日韩av免费观影| 日韩精品中文字幕有码专区| 91亚洲国产成人久久精品网站| 亚洲电影av在线| 2019亚洲日韩新视频| 日韩激情在线视频| 欧美日韩国产一区二区三区| 欧美日韩国产页| 麻豆乱码国产一区二区三区| 欧美日韩中文字幕| 国产精品偷伦视频免费观看国产| 亚洲一区二区国产| 一本一本久久a久久精品综合小说| 国产免费一区二区三区香蕉精| 性亚洲最疯狂xxxx高清| 国产亚洲精品久久久优势| 一本色道久久综合亚洲精品小说| 欧美精品在线免费观看| 久久天天躁狠狠躁夜夜躁2014| 97在线精品视频| 综合av色偷偷网| 欧美性xxxx极品hd满灌| 国产精品成人va在线观看| 国产成人精品亚洲精品| 国产日韩欧美日韩大片| 性欧美在线看片a免费观看| 在线精品视频视频中文字幕| 2020久久国产精品| 色偷偷噜噜噜亚洲男人的天堂| 欧美成年人视频网站欧美| 日韩欧美999| 国产一区二区三区免费视频| 正在播放欧美视频| 日韩电影中文 亚洲精品乱码| 国产精品久久久久久超碰| 欧美激情视频一区二区三区不卡| 在线中文字幕日韩| 国产精品福利片| 精品国产一区av| 欧美福利小视频| 在线视频日韩精品| 国产精品中文字幕在线观看| 欧美野外猛男的大粗鳮| 日韩av在线一区二区| 日韩大片在线观看视频| 欧美乱大交xxxxx| 九九精品在线播放| 亚洲社区在线观看| 正在播放欧美一区| 国产精品久久久久久av福利| 91精品综合久久久久久五月天| 国产91网红主播在线观看| 人体精品一二三区| 国产精品视频免费观看www| 尤物精品国产第一福利三区| 中文字幕在线观看亚洲| 91九色视频在线| 国产九九精品视频| 日韩中文字幕免费视频| 在线日韩中文字幕| 最近2019中文免费高清视频观看www99| 91色在线观看| 日韩一二三在线视频播| 91精品国产自产91精品| 欧美巨乳在线观看| 久久精品中文字幕电影| 精品毛片网大全| 91精品国产成人www| 欧美俄罗斯乱妇| 亚洲精选中文字幕| 亚洲free性xxxx护士hd| 尤物yw午夜国产精品视频明星| 久久91超碰青草是什么| 91爱爱小视频k| 51午夜精品视频| 国产欧美一区二区三区在线| 日韩精品视频免费在线观看| 26uuu国产精品视频| 欧美大学生性色视频| 一区二区欧美激情| 久久久久一本一区二区青青蜜月| 国产亚洲美女精品久久久| 亚洲国产欧美在线成人app| 欧美在线中文字幕| 欧美日产国产成人免费图片| 亚洲国产一区二区三区四区| 欧美一级黄色网| 欧美成人一区在线| 91久久精品日日躁夜夜躁国产| 羞羞色国产精品| 亚洲自拍中文字幕| 欧美在线亚洲一区| 亚洲三级av在线| 欧美另类99xxxxx| 精品视频久久久久久久| 欧美精品激情在线| 国产剧情久久久久久| 亚洲第一级黄色片| 亚洲人成电影网站色xx| 国产精品1234| 亚洲自拍av在线| 日韩av一区在线| 亚州av一区二区| 国内精品伊人久久| 国产成人精品在线观看| 国产亚洲精品美女久久久久| 久久精品成人欧美大片| 成人黄色在线播放| zzjj国产精品一区二区| 久久91超碰青草是什么| 国产精品女主播| 亚洲国产又黄又爽女人高潮的| 一本色道久久88综合日韩精品| 欧美成人免费视频| 亚洲xxxx在线| 自拍亚洲一区欧美另类| 尤物tv国产一区| 在线观看免费高清视频97| 亚洲日本成人女熟在线观看| 欧美精品在线播放| 国产精品欧美日韩一区二区| 日韩精品免费综合视频在线播放| 成人黄色大片在线免费观看| 日韩欧美成人免费视频| 日韩av片永久免费网站| 亚洲另类欧美自拍| 国产精品亚洲一区二区三区| 国模视频一区二区| xxxxx91麻豆| 成人国内精品久久久久一区| 欧美激情视频一区二区| 亚洲人成网站免费播放| 国产91对白在线播放|