標籤:
特性
Dapper 是一個單獨的檔案,可以放進你的項目中用來擴充你的IDbConnection介面.
它提供了三個助手:
執行一個查詢,並將結果映射到一個強型別集合中
注意:所有擴充方法假設串連已經開啟,如果串連關閉,他們將會失敗。
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);執行一個查詢,並將結果映射到一個動態類型集合中
該方法將執行SQL和返回一個動態集合。
public static IEnumerable<dynamic> Query (this IDbConnection cnn, string sql, object param = null, SqlTransaction transaction = null, bool buffered = true)
使用例子:
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);執行一個命令,不返回結果
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);多次執行一個命令
相同的預留位置允許您方便有效多次執行一個命令.
使用例子:
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 行 被插入: "1,1", "2,2" and "3,3"效能
Dapper的一個關鍵特性是效能。以下指標顯示對資料庫執行500次SELECT語句並返回資料對應到對象,需要多長時間。
效能測試分為三個表格:
- POCO序列化架構支援從資料庫到靜態類型化對象,通過使用原始的SQL。
- 動態序列化架構支援返回動態對象的列表。
- 典型的架構使用。通常典型架構使用不同於最佳的使用效能明智。通常它不會涉及編寫SQL。
500次查詢映射的效能-POCO序列化
| Method |
Duration |
Remarks |
Hand coded (using a SqlDataReader) |
47ms |
Can be faster |
Dapper ExecuteMapperQuery |
49ms |
| ServiceStack.OrmLite (QueryById) |
50ms |
| PetaPoco |
52ms |
| BLToolkit |
80ms |
| SubSonic CodingHorror |
107ms |
| NHibernate SQL |
104ms |
Linq 2 SQL ExecuteQuery |
181ms |
Entity framework ExecuteStoreQuery |
631ms |
500次查詢映射的效能-動態類型序列化
| Method |
Duration |
Remarks |
Dapper ExecuteMapperQuery (dynamic) |
48ms |
|
| Massive |
52ms |
| Simple.Data |
500次查詢映射的效能-經典架構使用
| Method |
Duration |
Remarks |
| Linq 2 SQL CompiledQuery |
81ms |
Not super typical involves complex code |
| NHibernate HQL |
118ms |
|
| Linq 2 SQL |
559ms |
|
| Entity framework |
859ms |
|
| SubSonic ActiveRecord.SingleOrDefault |
3619ms |
|
參數化查詢
參數傳遞匿名類。這允許您具名引數容易和使您能夠簡單剪下和粘貼SQL程式碼片段在查詢分析器和運行它們。
new {A = 1, B = "b"} // A 會被映射出參數 @A, B 對應 @B 集合參數的支援
Dapper允許您通過IEnumerable,自動化您的查詢參數.
使用例子:
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
緩衝和無緩衝的讀者
Dapper的預設行為是執行sql和緩衝整個reader在返回。這是理想的在大多數情況下,因為它最大限度地減少共用鎖定在資料庫和減少了資料庫在網路上的時間。
然而當執行查詢您可能需要減少記憶體佔用並根據需要只載入對象。
多個映射
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 = @idselect * from Orders where CustomerId = @idselect * 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).SingleOrDefault();
如果你想做的更漂亮你可以這樣:
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字串和varchar
Dapper支援varchar params,如果你是一個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緩衝。
我能在我的資料庫中使用嗎?
Dapper沒有DB具體的實現細節,它在所有工作。淨ADO提供者includingSQLite、SQL CE、火鳥、Oracle、MySQL、PostgreSQL和SQL伺服器。
Dapper - a simple object mapper for .Net