基于轻量级ORM框架Dapper的扩展说明

大道之行,天下为公。这篇文章主要讲述基于轻量级ORM框架Dapper的扩展说明相关的知识,希望能为你提供帮助。
这里简单的介绍一下本人基于Dapper作的一些简单的扩展,供大家参考。
为何要使用这款框架,相信大家看到下面排名就清楚了

基于轻量级ORM框架Dapper的扩展说明

文章图片

其实在各大网站上,我们大概都会看到这样的一个对比效果图,在超过500次poco serialization的过程中所表现的性能,我们发现dapper是第二名,
当然第一名谁也无法超越,越底层的当然久越快,同时也就越麻烦。
至于如何使用进行基本的数据操作,我这里就不再阐述,http://www.cnblogs.com/Sinte-Beuve/p/4231053.html这里介绍了Dapper的基本使用的方法。
一.文件说明,打包的文件如下
SqlMapperExtensions类:ORM扩展类,基于SQLMapper类的扩展。
SqlMapper类--Dapper原始类:一些底层封装代码,使用时可查看其实现原理。
生成实体类_Dapper_模板文件:用于动态生成实体类的模板,配合DOS生成工具使用。
二.扩展类新增的几个方法
SqlMapperExtensions类中新增: UpdateGiven()、InsertGiven()、GetPageList()方法。
UpdateGiven():更新时只更新赋值的字段
InsertGiven():插入时只插入赋值的字段
GetPageList():新增分页查询
另新增数据库环境支持Oracle
三.举栗子
这里用上面的方法来简单的测试一下。
1 using System; 2 using System.Collections.Generic; 3 using System.Data; 4 using System.Data.SqlClient; 5 using System.Linq; 6 using System.Text; 7 using System.Threading.Tasks; 8 using Dapper; 9 using System.Data.OracleClient; 10 using Dapper.Contrib.Extensions; 11 using Dapper.Contrib; 12 using Dapper.Model; 13 namespace ConsoleTest1 14 { 15class Program 16{ 18static IDbConnection conn = new OracleConnection("Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=*.*.*.*)(PORT=1521)))(CONNECT_DATA=https://www.songbingjia.com/android/(service_name =*))); Persist Security Info=True; User ID=*; Password=*;"); 19static void Main(string[] args) 20{ 21//创建Book表 22conn.Execute(@" create table Book (Id number, Name nvarchar2(100) not null),Remark nvarchar2(200)"); 23Console.WriteLine("Created database"); 24BOOK book = new BOOK(); 25book.NAME = "C#本质论"; 26book.ID = 1001; 27string query = "INSERT INTO Book(Id,Name)VALUES(@Id,@Name)"; 28//对对象进行操作 29conn.Execute(query, book); //原始操作 传入sql语句和参数 30 31////以下是扩展中的方式 32//直接用Insert虽然只给了部分字段,但会插入所有字段,造成数据库的默认值会被覆盖的情况 33conn.Insert< BOOK> (new BOOK { ID = 1004, NAME = "Dapper" }); 34conn.InsertGiven< BOOK> (new BOOK { ID = 1004, NAME = "Dapper" }); 35//每次执行Update方法也是会更新所有字段,没赋值的字段会覆盖掉原始数据库的值 36conn.Update< BOOK> (new BOOK { ID = 1004, NAME = "Dapper" }); 37conn.UpdateGiven< BOOK> (new BOOK { ID = 1004, NAME = "update Dos way" }); 38////以下是分页查询,有一个重载 39long longCount; 40var sortlist=new List< ISort> (); 41sortlist.Add(new Sort{ PropertyName="id",Ascending=true}); 42//该方法要传入一个长整型变量供传递出查询的总量 43var pagebook = conn.GetPageList< BOOK> (0, 10, out longCount, new BOOK { ID=1004}, sortlist); 44//该重载不需要传入长整型变量 45var pagebook2 = conn.GetPageList< BOOK> (0, 10, null, sortlist); 46 47} 48} 49 50 }

其中具体方式的实现分别如下:
基于轻量级ORM框架Dapper的扩展说明

文章图片
基于轻量级ORM框架Dapper的扩展说明

文章图片
1/// < summary> 2/// Inserts an entity into table "Ts" and returns identity id.(Insert the given fields) 3/// < /summary> 4/// < param name="connection"> Open SqlConnection< /param> 5/// < param name="entityToInsert"> Entity to insert< /param> 6/// < returns> Identity of inserted entity< /returns> 7public static long InsertGiven< T> (this IDbConnection connection, T entityToInsert, IDbTransaction transaction = null, int? commandTimeout = null) where T : Entity 8{ 9var type = typeof(T); 10var name = GetTableName(type); 11var mfields = entityToInsert.GetModifyFields(); 12if (null == mfields || mfields.Count == 0) 13return -1; 14var sbColumnList = new StringBuilder(null); 15SetSqlConnectTag(connection); //根据不同数据库设置标记符 SqlServer@ Oracle: 16var keyProperties = KeyPropertiesCache(type); 17for (var i = 0; i < mfields.Count; i++) 18{ 19sbColumnList.AppendFormat("{0}", mfields[i].Field); 20if (i < mfields.Count - 1) 21sbColumnList.Append(", "); 22} 23var sbParameterList = new StringBuilder(null); 24for (var i = 0; i < mfields.Count; i++) 25{ 26sbParameterList.AppendFormat("{0}{1}", SqlConnectTag, mfields[i].Field); 27if (i < mfields.Count - 1) 28sbParameterList.Append(", "); 29} 30var adapter = GetFormatter(connection); 31return adapter.Insert(connection, transaction, commandTimeout, name, sbColumnList.ToString(), 32sbParameterList.ToString(), keyProperties, entityToInsert); 33}

InsertGiven
基于轻量级ORM框架Dapper的扩展说明

文章图片
基于轻量级ORM框架Dapper的扩展说明

文章图片
1/// < summary> 2/// Updates entity in table "Ts", checks if the entity is modified if the entity is tracked by the Get() extension. 3/// update the given fileds 4/// < /summary> 5/// < typeparam name="T"> Type to be updated< /typeparam> 6/// < param name="connection"> Open SqlConnection< /param> 7/// < param name="entityToUpdate"> Entity to be updated< /param> 8/// < returns> true if updated, false if not found or not modified (tracked entities)< /returns> 9public static bool UpdateGiven< T> (this IDbConnection connection, T entityToUpdate, IDbTransaction transaction = null, int? commandTimeout = null) where T : Entity 10{ 11var proxy = entityToUpdate as IProxy; 12if (proxy != null) 13{ 14if (!proxy.IsDirty) return false; 15} 16 17var type = typeof(T); 18 19var keyProperties = KeyPropertiesCache(type); 20if (!keyProperties.Any()) 21throw new ArgumentException("Entity must have at least one [Key] property"); 22 23var name = GetTableName(type); 24 25var mfields = entityToUpdate.GetModifyFields(); 26if (null == mfields || mfields.Count == 0) 27return false; 28for (var i = 0; i < keyProperties.Count(); i++) 29{//排除主键 30var property = keyProperties.ElementAt(i); 31if (mfields.Select(t => t.Field).Contains(property.Name)) 32mfields.Remove(mfields.FirstOrDefault(t=> t.Field==property.Name)); 33} 34var sb = new StringBuilder(); 35sb.AppendFormat("update {0} set ", name); 36SetSqlConnectTag(connection); //根据不同数据库设置标记符 SqlServer@ Oracle: 37for (var i = 0; i < mfields.Count; i++) 38{ 39sb.AppendFormat("{0} = {2}{1}", mfields[i].Field, mfields[i].Field, SqlConnectTag); 40if (i < mfields.Count - 1) 41sb.AppendFormat(", "); 42} 43sb.Append(" where "); 44for (var i = 0; i < keyProperties.Count(); i++) 45{ 46var property = keyProperties.ElementAt(i); 47sb.AppendFormat("{0} = {2}{1}", property.Name, property.Name, SqlConnectTag); 48if (i < keyProperties.Count() - 1) 49sb.AppendFormat(" and "); 50} 51var updated = connection.Execute(sb.ToString(), entityToUpdate, commandTimeout: commandTimeout, transaction: transaction); 52return updated > 0; 53}

UpdateGiven
1/// < summary> 2/// Paging 3/// < /summary> 4/// < typeparam name="T"> 传入实体类型< /typeparam> 5/// < param name="connection"> 此连接< /param> 6/// < param name="pageIndex"> 第几页:0为第一页开始< /param> 7/// < param name="pageSize"> 每页数量< /param> 8/// < param name="allRowsCount"> 返回满足条件总量< /param> 9/// < param name="entityToPredicate"> 条件:实体传入< /param> 10/// < param name="sort"> 排序条件:ISort列表方式传入< /param> 11/// < param name="buffered"> 是否缓存< /param> 12/// < returns> < /returns> 13public static IEnumerable< T> GetPageList< T> (this IDbConnection connection, int pageIndex, int pageSize, out long allRowsCount, 14T entityToPredicate = null, IList< ISort> sort = null, bool buffered = true) where T : Entity 15{ 16DynamicParameters dynamicParameters = new DynamicParameters(); 17var type = typeof(T); 18SetSqlConnectTag(connection); //根据不同数据库设置标记符 SqlServer@ Oracle: 19var keys = KeyPropertiesCache(type); 20if (keys.Count() > 1) 21throw new DataException("Get< T> only supports an entity with a single [Key] property"); 22if (!keys.Any()) 23throw new DataException("Get< T> only supports en entity with a [Key] property"); 24 25var onlyKey = keys.First(); 26StringBuilder innersql = new StringBuilder(string.Format("SELECT * FROM {0}", 27GetTableName(type))); 28if (entityToPredicate != null) 29{ 30var mfields = entityToPredicate.GetModifyFields(); 31innersql.Append(" where "); 32for (var i = 0; i < mfields.Count; i++) 33{ 34innersql.AppendFormat("{0} = {2}{1}", mfields[i].Field, mfields[i].Field, SqlConnectTag); 35if (i < mfields.Count - 1) 36innersql.AppendFormat(", "); 37dynamicParameters.Add(mfields[i].Field, mfields[i].NewValue); 38} 39} 40if (sort != null & & sort.Any()) 41{ 42innersql.Append(" ORDER BY ") 43.Append(sort.Select(s => s.PropertyName + (s.Ascending ? " ASC" : " DESC")).AppendStrings()); 44} 45allRowsCount = connection.Query(innersql.ToString(), entityToPredicate).Count(); 46Dictionary< string, object> parameters = new Dictionary< string, object> (); 47string sql = GetFormatter(connection).GetPagingSql(innersql.ToString(), pageIndex, pageSize, parameters); 48foreach (var parameter in parameters) 49{ 50dynamicParameters.Add(parameter.Key, parameter.Value); 51} 52return connection.Query< T> (sql, dynamicParameters); 53}

下面我们来调试一下来看看Insert和InsertGiven、Update和UpdateGiven的区别吧
1////以下是扩展中的方式 2//直接用Insert虽然只给了部分字段,但会插入所有字段,造成数据库的默认值会被覆盖的情况 3conn.Insert< BOOK> (new BOOK { ID = 1004, NAME = "Dapper" }); 4conn.InsertGiven< BOOK> (new BOOK { ID = 1004, NAME = "Dapper" }); 5//每次执行Update方法也是会更新所有字段,没赋值的字段会覆盖掉原始数据库的值 6conn.Update< BOOK> (new BOOK { ID = 1004, NAME = "Dapper" }); 7conn.UpdateGiven< BOOK> (new BOOK { ID = 1004, NAME = "update Dos way" });

Insert生成的sql语句:
基于轻量级ORM框架Dapper的扩展说明

文章图片

InsertGiven生成的sql语句:
基于轻量级ORM框架Dapper的扩展说明

文章图片

Update生成的sql语句:
基于轻量级ORM框架Dapper的扩展说明

文章图片

UpdateGiven生成的sql语句:
基于轻量级ORM框架Dapper的扩展说明

文章图片

想必扩展的方法个中缘由就一清二楚了。
四.实体类生成
其中BOOK实体类如何生成?这里借鉴了DOS生成实体类工具,并新增了一个模板文件-> 生成实体类_Dapper_模板文件.tpl
打开DOSTOOL的Debug文件,将其放入模板文件中,重新打开DOSTOOL文件便可看见新增了一个模板,选择其模板,生成代码即可。
基于轻量级ORM框架Dapper的扩展说明

文章图片

基于轻量级ORM框架Dapper的扩展说明

文章图片

 
 
基于轻量级ORM框架Dapper的扩展说明

文章图片

【基于轻量级ORM框架Dapper的扩展说明】以上。

    推荐阅读