根据您的个性需求进行定制 先人一步 抢占小程序红利时代
在开发带数据库的.NET系统中我使用过各种方式,包括直接使用ADO.NET、使用基于ADO.NET封装的各类工具(其中有自己封装的)、还有各类ORM类库,比如NHibernate、MyBatisNet、Linq to SQL、Entity Framwrok等,在上面的工具或类库中,MyBatisNet一段时间曾是我的最爱:由于它基于XML的配置可以灵活适应一些特殊的场景,不过有时候在面对中小型项目时又觉得MyBatisNet有些大材小用,此外还有一个原因是MyBatisNet这个基于Java的MyBatis改造而来的项目最近几乎没有更新了。
很早就听说过Dapper这个类库了,只不过一直没有尝试使用,但是很早就知道它是国外大型IT问答社区StackOverFlow最早开发并开源的。最近用了一下,感觉确实很方便。Dapper的源代码放在github上托管,并且可以用NuGet方式添加到项目中,只不过我现在开发的桌面软件有一部分用户还在使用WindowsXP系统,因此不能使用高于.NET Framrwork4.5以上版本开发且开发工具是Visual Studio 2015,这也限制了我不能使用最新版本的Dapper,于是我选择了Dapper 1.50.2这个版本。
我们可以在Visual Studio 2015中直接使用NuGet来添加,具体办法就是“工具”-“NuGet包管理器”-“管理解决方案的BuGet程序包”,如下图所示:
然后在弹出的窗口中搜索“Dapper”,如下图所示:
在上述界面中可以选择安装到当前解决方案的那些项目中,并且还可以指定Dapper的版本。
我们提供的服务有:网站建设、网站设计、微信公众号开发、网站优化、网站认证、延长ssl等。为上千企事业单位解决了网站和推广的问题。提供周到的售前咨询和贴心的售后服务,是有科学管理、有技术的延长网站制作公司
本文的描述都是针对Dapper 1.50.2版本。
扩展方法介绍
在介绍Dapper之前首先要介绍一下.NE中的扩展方法。扩展方法是.NET3.5添加的一个特性,使用扩展方法可以让你为现有的类扩展方法而无需创建新的派生类。下面以一个例子来说明:
在我解析某个XML文件节点时,需要读取某个节点的属性,但是这个节点并不是一直有这个属性值,如下:
为了避免name属性不存在时抛出异常,我必须先进行判断,如下:
string name=string.Empty;
if (subNetworkNode.Attributes["name"] != null)
{
name=subNetworkNode.Attributes["name"].Value;
}
如果一个XML节点里有几个可能不存在的属性时,就需要处处这样判断了,于是我对代码进行了改进,针对此类情况定义了扩展方法,方法如下:
public static class ExtendMethodClass
{
///
/// 获取指定属性的值,如果没有设置指定属性名,则返回空字符串
///
/// XML节点的属性集合
/// 属性名
///
public static string GetAttributeValue(this XmlAttributeCollection attributes,string attributeName)
{
if (string.IsNullOrEmpty(attributeName))
{
throw new ArgumentNullException("attributeName", "不能为空");
}
if (attributes == null||attributes[attributeName]==null)
{
return string.Empty;
}
return attributes[attributeName].Value;
}
}
这样一来,原来的代码就可以写成如下了:
string name = subNetworkNode.Attributes.GetAttributeValue("name");
初一看,就像是XmlAttributeCollection这类原来就有GetAttributeValue(string attributeName)这样一个方法,其实这个方式是我们自己扩展的。
定义扩展方法有几点:
1、定义扩展方法的类必须用static修饰,即必须为静态类。
2、定义的扩展方法必须用static修饰,即必须为静态方法,同时方法的第一个参数前必须加this修饰,this后必须是类名,表示为this后的类添加扩展方法,如本例中this XmlAttributeCollection attributes表示为XmlAttributeCollection这个类添加扩展方法,如果需要在方法体内访问XmlAttributeCollection这个类的实例,通过后面的attributes参数即可(注意这个参数的名称可以随便取)。
Dapper介绍
通过上面的介绍,大家可以初步了解扩展方法是怎么回事。其实Dapper主要也是用了扩展方法为IDbConnection和IDataReader添加扩展方法,比如在SqlMapper.cs中有如下代码为IDbConnection添加扩展方法(节选):
//
/// Execute parameterized SQL.
///
/// The connection to query on.
/// The SQL to execute for this query.
/// The parameters to use for this query.
/// The transaction to use for this query.
/// Number of seconds before command execution timeout.
/// Is it a stored proc or a batch?
/// The number of rows affected.
public static int Execute(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null)
{
var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered);
return ExecuteImpl(cnn, ref command);
}
///
/// Execute parameterized SQL.
///
/// The connection to execute on.
/// The command to execute on this connection.
/// The number of rows affected.
public static int Execute(this IDbConnection cnn, CommandDefinition command) => ExecuteImpl(cnn, ref command);
在SqlMapper.IDataReader.cs为IDataReader添加扩展方法的代码(节选):
///
/// Parses a data reader to a sequence of data of the supplied type. Used for deserializing a reader without a connection, etc.
///
/// The type to parse from the .
/// The data reader to parse results from.
public static IEnumerable Parse(this IDataReader reader)
{
if (reader.Read())
{
var deser = GetDeserializer(typeof(T), reader, 0, -1, false);
do
{
yield return (T)deser(reader);
} while (reader.Read());
}
}
///
/// Parses a data reader to a sequence of data of the supplied type (as object). Used for deserializing a reader without a connection, etc.
///
/// The data reader to parse results from.
/// The type to parse from the .
public static IEnumerable