标签:
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语句并返回数据映射到对象,需要多长时间。
性能测试分为三个表格:
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 |
Method | Duration | Remarks |
---|---|---|
Dapper ExecuteMapperQuery (dynamic) |
48ms | |
Massive | 52ms | |
Simple.Data |
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 = @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).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");
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
标签:
原文地址:http://www.cnblogs.com/szw1993/p/4776803.html