Dapper使用方法
这里记下Dapper容易忘的使用方法:
返回的数据可以有相同名称的列,会分配到不同的类上,默认使用Id这个列作为分割列
connection.Open(); //手动打开的话会保持长连接,否则每次查询之后会关闭连接
构造函数的参数类型必须严格与数据库字段类型相同
/// <summary>
/// 也可以直接用数组
/// </summary>
public void TestListOfAnsiStrings()
{
var results = connection.Query<string>("select * from (select 'a' str union select 'b' union select 'c') X where str in @strings",
new { strings = new[] { new DbString { IsAnsi = true, Value = "a" }, new DbString { IsAnsi = true, Value = "b" } } }).ToList(); results[].IsEqualTo("a");
results[].IsEqualTo("b");
}
映射类型支持枚举及可为空枚举,但是枚举必须继承short,int,long等其中一种类型,并且与数据库字段类型必须相同,需要注意的是mysql默认数字为long类型
/// <summary>
/// 可以执行多条语句
/// </summary>
public void TestExecuteCommand()
{
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 = , b = }).IsEqualTo();
}
/// <summary>
/// 执行语句,返回输出参数值
/// </summary>
public void TestExecuteCommandWithHybridParameters()
{
var p = new DynamicParameters(new { a = , b = });
p.Add("c", dbType: DbType.Int32, direction: ParameterDirection.Output);
connection.Execute(@"set @c = @a + @b", p);
p.Get<int>("@c").IsEqualTo();
}
/// <summary>
/// 好方法,返回无实体类数据,使用动态类型
/// </summary>
public void TestExpandWithNullableFields()
{
var row = connection.Query("select null A, 2 B").Single(); ((int?)row.A)
.IsNull(); ((int?)row.B)
.IsEqualTo();
}
/// <summary>
/// 批量插入的简洁写法,Execute返回成功执行的数量,报错则跳出
/// </summary>
public void TestExecuteMultipleCommand()
{
connection.Execute("create table #t(i int)");
try
{
int tally = connection.Execute(@"insert #t (i) values(@a)", new[] { new { a = }, new { a = }, new { a = }, new { a = } });
int sum = connection.Query<int>("select sum(i) from #t").First();
tally.IsEqualTo();
sum.IsEqualTo();
}
finally
{
connection.Execute("drop table #t");
}
}
class TestObj
{
public int _internal;
internal int Internal { set { _internal = value; } } public int _priv;
private int Priv { set { _priv = value; } } private int PrivGet { get { return _priv; } }
} /// <summary>
/// ????私有字段也能映射
/// </summary>
public void TestSetPrivate()
{
connection.Query<TestObj>("select 10 as [Priv]").First()._priv.IsEqualTo();
}
/// <summary>
/// 好方法,返回无实体类数据,使用动态类型
/// </summary>
public void TestExpandWithNullableFields()
{
var row = connection.Query("select null A, 2 B").Single(); ((int?)row.A)
.IsNull(); ((int?)row.B)
.IsEqualTo();
}
/// <summary>
/// datareader方式的查询,不释放连接,如果有新的连接会报错
/// </summary>
public void TestEnumeration()
{
var en = connection.Query<int>("select 1 as one union all select 2 as one", buffered: false);
var i = en.GetEnumerator();
i.MoveNext(); bool gotException = false;
try
{
var x = connection.Query<int>("select 1 as one", buffered: false).First();
}
catch (Exception)
{
gotException = true;
} while (i.MoveNext())
{ } // should not exception, since enumertated
en = connection.Query<int>("select 1 as one", buffered: false); gotException.IsTrue();
}
/// <summary>
/// QueryMultiple可以返回多结果集
/// </summary>
public void TestMultiMapGridReader()
{
var createSql = @"
create table #Users (Id int, Name varchar(20))
create table #Posts (Id int, OwnerId int, Content varchar(20)) insert #Users values(99, 'Sam')
insert #Users values(2, 'I am') insert #Posts values(1, 99, 'Sams Post1')
insert #Posts values(2, 99, 'Sams Post2')
insert #Posts values(3, null, 'no ones post')
";
connection.Execute(createSql); var sql =@"select p.*, u.Id, u.Name + '0' Name from #Posts p
left join #Users u on u.Id = p.OwnerId
Order by p.Id select p.*, u.Id, u.Name + '1' Name from #Posts p
left join #Users u on u.Id = p.OwnerId
Order by p.Id
"; var grid = connection.QueryMultiple(sql); for (int i = ; i < ; i++)
{
var data = grid.Read<Post, User, Post>((post, user) => { post.Owner = user; return post; }).ToList();
var p = data.First(); p.Content.IsEqualTo("Sams Post1");
p.Id.IsEqualTo();
p.Owner.Name.IsEqualTo("Sam" + i);
p.Owner.Id.IsEqualTo(); data[].Owner.IsNull();
} connection.Execute("drop table #Users drop table #Posts"); }
/// <summary>
/// buffered是指将数据都读取出来,释放datareader,否则是不能再次打开datareader
/// </summary>
public void TestQueryMultipleNonBufferedIncorrectOrder()
{
using (var grid = connection.QueryMultiple("select 1; select 2; select @x; select 4", new { x = }))
{
var a = grid.Read<int>(false);
try
{
var b = grid.Read<int>(false);
throw new InvalidOperationException(); // should have thrown
}
catch (InvalidOperationException)
{
// that's expected
} }
}
public void TestQueryMultipleNonBufferedCcorrectOrder()
{
using (var grid = connection.QueryMultiple("select 1; select 2; select @x; select 4", new { x = }))
{
var a = grid.Read<int>(false).Single(); //Single将会释放datareader,只能运行一次
var b = grid.Read<int>(false).Single();
var c = grid.Read<int>(false).Single();
var d = grid.Read<int>(false).Single(); a.Equals();
b.Equals();
c.Equals();
d.Equals();
}
}
splitOn用于分割多个实体类的字段
Dapper支持返回dynamic类型
/// <summary>
/// 支持将字符串转为枚举
/// </summary>
public void TestEnumStrings()
{
connection.Query<TestEnumClassNoNull>("select 'BLA' as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla);
connection.Query<TestEnumClassNoNull>("select 'bla' as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla); connection.Query<TestEnumClass>("select 'BLA' as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla);
connection.Query<TestEnumClass>("select 'bla' as [EnumEnum]").First().EnumEnum.IsEqualTo(TestEnum.Bla);
}
/// <summary>
/// ExpandoObject有什么用
/// </summary>
public void TestSupportForExpandoObjectParameters()
{
dynamic p = new ExpandoObject();
p.name = "bob";
object parameters = p;
string result = connection.Query<string>("select @name", parameters).First();
result.IsEqualTo("bob");
}
/// <summary>
/// 执行存储过程
/// </summary>
public void TestProcSupport()
{
var p = new DynamicParameters();
p.Add("a", );
p.Add("b", dbType: DbType.Int32, direction: ParameterDirection.Output);
p.Add("c", dbType: DbType.Int32, direction: ParameterDirection.ReturnValue); connection.Execute(@"create proc #TestProc
@a int,
@b int output
as
begin
set @b = 999
select 1111
return @a
end");
connection.Query<int>("#TestProc", p, commandType: CommandType.StoredProcedure).First().IsEqualTo(); p.Get<int>("c").IsEqualTo();
p.Get<int>("b").IsEqualTo(); }
/// <summary>
/// DbString用于代替数据库字符串类型
/// </summary>
public void TestDbString()
{
var obj = connection.Query("select datalength(@a) as a, datalength(@b) as b, datalength(@c) as c, datalength(@d) as d, datalength(@e) as e, datalength(@f) as f",
new
{
a = new DbString { Value = "abcde", IsFixedLength = true, Length = , IsAnsi = true },
b = new DbString { Value = "abcde", IsFixedLength = true, Length = , IsAnsi = false },
c = new DbString { Value = "abcde", IsFixedLength = false, Length = , IsAnsi = true },
d = new DbString { Value = "abcde", IsFixedLength = false, Length = , IsAnsi = false },
e = new DbString { Value = "abcde", IsAnsi = true },
f = new DbString { Value = "abcde", IsAnsi = false },
}).First();
((int)obj.a).IsEqualTo();
((int)obj.b).IsEqualTo();
((int)obj.c).IsEqualTo();
((int)obj.d).IsEqualTo();
((int)obj.e).IsEqualTo();
((int)obj.f).IsEqualTo();
}
/// <summary>
/// Query返回的结果是动态的
/// </summary>
public void TestFastExpandoSupportsIDictionary()
{
var row = connection.Query("select 1 A, 'two' B").First() as IDictionary<string, object>;
row["A"].IsEqualTo();
row["B"].IsEqualTo("two");
}
class Parent
{
public int Id { get; set; }
public readonly List<Child> Children = new List<Child>();
}
class Child
{
public int Id { get; set; }
}
/// <summary>
/// 可以在map的方法内对数据进行处理
/// </summary>
public void ParentChildIdentityAssociations()
{
var lookup = new Dictionary<int, Parent>();
var parents = connection.Query<Parent, Child, Parent>(@"select 1 as [Id], 1 as [Id] union all select 1,2 union all select 2,3 union all select 1,4 union all select 3,5",
(parent, child) =>
{
Parent found;
if (!lookup.TryGetValue(parent.Id, out found))
{
lookup.Add(parent.Id, found = parent);
}
found.Children.Add(child);
return found;
}).Distinct().ToDictionary(p => p.Id);
parents.Count().IsEqualTo();
parents[].Children.Select(c => c.Id).SequenceEqual(new[] { , , }).IsTrue();
parents[].Children.Select(c => c.Id).SequenceEqual(new[] { }).IsTrue();
parents[].Children.Select(c => c.Id).SequenceEqual(new[] { }).IsTrue();
}
SqlMapper.IDynamicParameters是参数的基类,可通过重写来封装自己的DB参数
/// <summary>
/// DynamicParameters的使用
/// </summary>
public void TestAppendingAnonClasses()
{
DynamicParameters p = new DynamicParameters();
p.AddDynamicParams(new { A = , B = });
p.AddDynamicParams(new { C = , D = }); var result = connection.Query("select @A a,@B b,@C c,@D d", p).Single(); ((int)result.a).IsEqualTo();
((int)result.b).IsEqualTo();
((int)result.c).IsEqualTo();
((int)result.d).IsEqualTo();
}
public void TestAppendingADictionary()
{
var dictionary = new Dictionary<string, object>();
dictionary.Add("A", );
dictionary.Add("B", "two"); DynamicParameters p = new DynamicParameters();
p.AddDynamicParams(dictionary); var result = connection.Query("select @A a, @B b", p).Single(); ((int)result.a).IsEqualTo();
((string)result.b).IsEqualTo("two");
}
/// <summary>
/// 使用事务
/// </summary>
public void TestTransactionCommit()
{
try
{
connection.Execute("create table #TransactionTest ([ID] int, [Value] varchar(32));"); using (var transaction = connection.BeginTransaction())
{
connection.Execute("insert into #TransactionTest ([ID], [Value]) values (1, 'ABC');", transaction: transaction); transaction.Commit();
} connection.Query<int>("select count(*) from #TransactionTest;").Single().IsEqualTo();
}
finally
{
connection.Execute("drop table #TransactionTest;");
}
}
/// <summary>
/// 使用事务方法二
/// </summary>
public void TestCommandWithInheritedTransaction()
{
connection.Execute("create table #TransactionTest ([ID] int, [Value] varchar(32));"); try
{
using (var transaction = connection.BeginTransaction())
{
var transactedConnection = new TransactedConnection(connection, transaction); transactedConnection.Execute("insert into #TransactionTest ([ID], [Value]) values (1, 'ABC');"); transaction.Rollback();
} connection.Query<int>("select count(*) from #TransactionTest;").Single().IsEqualTo();
}
finally
{
connection.Execute("drop table #TransactionTest;");
}
}
/// <summary>
/// 自定义映射方法
/// </summary>
public void TestCustomTypeMap()
{
// default mapping
var item = connection.Query<TypeWithMapping>("Select 'AVal' as A, 'BVal' as B").Single();
item.A.IsEqualTo("AVal");
item.B.IsEqualTo("BVal"); // custom mapping
var map = new CustomPropertyTypeMap(typeof(TypeWithMapping),
(type, columnName) => type.GetProperties().Where(prop => prop.GetCustomAttributes(false).OfType<DescriptionAttribute>().Any(attr => attr.Description == columnName)).FirstOrDefault());
SqlMapper.SetTypeMap(typeof(TypeWithMapping), map); item = connection.Query<TypeWithMapping>("Select 'AVal' as A, 'BVal' as B").Single();
item.A.IsEqualTo("BVal");
item.B.IsEqualTo("AVal"); // reset to default
SqlMapper.SetTypeMap(typeof(TypeWithMapping), null);
item = connection.Query<TypeWithMapping>("Select 'AVal' as A, 'BVal' as B").Single();
item.A.IsEqualTo("AVal");
item.B.IsEqualTo("BVal");
} public class TypeWithMapping
{
[Description("B")]
public string A { get; set; } [Description("A")]
public string B { get; set; }
}
/// <summary>
/// 动态查询结果可以直接转化为IDictionary
/// </summary>
public void TestDynamicMutation()
{
var obj = connection.Query("select 1 as [a], 2 as [b], 3 as [c]").Single();
((int)obj.a).IsEqualTo();
IDictionary<string, object> dict = obj;
Assert.Equals(, dict.Count);
Assert.IsTrue(dict.Remove("a"));
Assert.IsFalse(dict.Remove("d"));
Assert.Equals(, dict.Count);
dict.Add("d", );
Assert.Equals(, dict.Count);
Assert.Equals("b,c,d", string.Join(",", dict.Keys.OrderBy(x => x)));
Assert.Equals("2,3,4", string.Join(",", dict.OrderBy(x => x.Key).Select(x => x.Value))); Assert.Equals(, (int)obj.b);
Assert.Equals(, (int)obj.c);
Assert.Equals(, (int)obj.d);
try
{
((int)obj.a).IsEqualTo();
throw new InvalidOperationException("should have thrown");
}
catch (RuntimeBinderException)
{
// pass
}
}
public void TestIssue131()
{
var results = connection.Query<dynamic, int, dynamic>(
"SELECT 1 Id, 'Mr' Title, 'John' Surname, 4 AddressCount",
(person, addressCount) =>
{
return person;
},
splitOn: "AddressCount"
).FirstOrDefault(); var asDict = (IDictionary<string, object>)results; asDict.ContainsKey("Id").IsEqualTo(true);
asDict.ContainsKey("Title").IsEqualTo(true);
asDict.ContainsKey("Surname").IsEqualTo(true);
asDict.ContainsKey("AddressCount").IsEqualTo(false);
}
/// <summary>
/// 强制指定映射范围
/// </summary>
public void TestSplitWithMissingMembers()
{
var result = connection.Query<Topic, Profile, Topic>(
@"select 123 as ID, 'abc' as Title,
cast('2013-1-1' as datetime) as CreateDate,
'ghi' as Name, 'def' as Phone",
(T, P) => { T.Author = P; return T; },
null, null, true, "ID,Name").Single(); result.ID.Equals();
result.Title.Equals("abc");
result.CreateDate.Equals(new DateTime(, , ));
result.Name.IsNull();
result.Content.IsNull(); result.Author.Phone.Equals("def");
result.Author.Name.Equals("ghi");
result.Author.ID.Equals();
result.Author.Address.IsNull();
}
public class Profile
{
public int ID { get; set; }
public string Name { get; set; }
public string Phone { get; set; }
public string Address { get; set; }
//public ExtraInfo Extra { get; set; }
} public class Topic
{
public int ID { get; set; }
public string Title { get; set; }
public DateTime CreateDate { get; set; }
public string Content { get; set; }
public int UID { get; set; }
public int TestColum { get; set; }
public string Name { get; set; }
public Profile Author { get; set; }
//public Attachment Attach { get; set; }
}
class param {
public int Age { get; set; }
public string MName { get; set; }
}
/// <summary>
/// 支持使用实体传递参数,实体不需与sql变量一一对应
/// </summary>
public void TestBindObjectParameters()
{
var car = new param()
{
Age = ,
MName = "fff",
};
var p = new DynamicParameters(car);
var val = connection.Query("select ?Age A ", p);
}
Dapper使用方法的更多相关文章
- Dapper使用方法:dapper-dot-net/Tests/Tests.cs解析(1)方法:TestMultiMapWithConstructor
sql: SELECT * FROM users; SELECT * FROM posts; SELECT * FROM Posts p LEFT JOIN Users u ON u.Id= p.Ow ...
- Dapper学习 - Dapper.Rainbow(三) - Read
前面已经介绍了新增/修改/删除了, 接下来介绍一下Rainbow的Read方法. 一.Read -- Rainbow原生 1. 先看测试代码 var conStr = ConfigurationMan ...
- mvc+webapi+dapper+ef codefirst项目搭建
首先项目是mvc5+webapi2.0+orm数据处理(dapper)+ef动态创建数据库. 1.项目框架层次结构: mvc项目根据不同的业务和功能进行不同的区域划分[今后项目维护起来方便],mode ...
- 初识Dapper
16年年底开发一个项目,拍卖的项目,对于我这个不入流的程序员来说,雪微是个挑战.程序猿这个行业就是学到老用到老吧.个人比较喜欢sql原生的写法,对EF 还是不怎么感冒,EF 虽然强大,但是用起来还不怎 ...
- 基于Dapper的分页实现,支持筛选,排序,结果集总数,非存储过程
简介 之前事先搜索了下博客园上关于Dapper分页的实现,有是有,但要么是基于存储过程,要么支持分页,而不支持排序,或者搜索条件不是那么容易维护. 代码 首先先上代码: https://github. ...
- ORM之Dapper运用
一.前言 上一篇[分层架构设计]我们已经有了架构的轮廓,现在我们就在这个轮廓里面造轮子.项目要想开始,肯定先得确定ORM框架,目前市面上的ORM框架有很多,对于.net人员来说很容易就想到以ADO.N ...
- C# 数据操作系列 - 18 让Dapper更强的插件
0. 前言 在前一篇中我们讲到了Dapper的应用,但是给我们的感觉Dapper不像个ORM更像一个IDbConnection的扩展.是的,没错.在实际开发中我们经常用Dapper作为对EF Core ...
- mvc+webapi 项目架构
首先项目是mvc5+webapi2.0+orm-dapper+ef codefirst+redis+quartz.net+actionmq. 1.项目框架层次结构: 这个mvc项目根据不同的业务和功能 ...
- 项目架构mvc+webapi
mvc+webapi 项目架构 首先项目是mvc5+webapi2.0+orm-dapper+ef codefirst. 1.项目框架层次结构: 这个mvc项目根据不同的业务和功能进行不同的区域划分, ...
随机推荐
- jQuery点击图片弹出大图遮罩层
使用jQuery插件HoverTreeShow弹出遮罩层显示大图 效果体验:http://hovertree.com/texiao/hovertreeshow/ 在开发HoverTreeTop项目的产 ...
- CSS3 动画记
css3 动画 在CSS3中可以通过animation创建复杂的动画序列,像transition属性一样用来控制CSS的属性实现动画效果. animation实现动画效果主要由两个部分组成. 通过类似 ...
- NVelocity 实现简单的留言板
留言版简单实现 -------------------------------------------------------------------------------------------- ...
- Jersey(1.19.1) - Sub-resources
@Path may be used on classes and such classes are referred to as root resource classes. @Path may al ...
- Linux 命令 - chown: 更改文件的所有者和所属群组
chown 命令用来更改文件或者目录的所有者和所属群组.使用这个命令需要超级用户的权限. 命令格式 chown [OPTION]... [OWNER][:[GROUP]] FILE... chown ...
- Git CMD - mv: Move or rename a file, a directory, or a symlink
命令格式 git mv [-v] [-f] [-n] [-k] <source> <destination> git mv [-v] [-f] [-n] [-k] <so ...
- 【Android】ADB常用指令与logcat日志(转)
ADB命令简介 ADB是一个功能强大的命令行工具.通过它可以直接和模拟器或真机进行交互.它是一个具有客户端和服务器端的程序. 它主要由三个部分组成: 客户端,它运行在你的开发机上,你可以通过执行adb ...
- Microsoft Dynamics CRM 2011的组织服务中的RetrieveMultiple方法(转)
本篇文章,介绍Microsoft Dynamics CRM 2011的组织服务中的RetrieveMultiple方法. RetreiveMultiple方法,用于获取实体的多个实例,该方法的签名如下 ...
- 【poj4011】Automated Telephone Exchange
题目:Automated Telephone Exchange poj URL:http://poj.org/problem?id=4011 原题如下图: 题意: 就是一个三位数减去两个小于或等于99 ...
- (转)在SQL中取出字符串中数字部分或在SQL中取出字符部分
近来在开发一个项目时,一包含数字的字符串,需要取出中间的数字部分进行排序.经过baidu搜索.并结合自己项目的需求,编写了一个自定义的SQL函数用供项目中使用. /****** Object: Use ...