基于轻量级ORM框架Dapper的扩展说明
这里简单的介绍一下本人基于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 { 15 class Program 16 { 18 static IDbConnection conn = new OracleConnection("Data Source=(DESCRIPTION=(ADDRESS_LIST=(ADDRESS=(PROTOCOL=TCP)(HOST=*.*.*.*)(PORT=1521)))(CONNECT_DATA=(service_name =*)));Persist Security Info=True;User ID=*; Password=*;"); 19 static void Main(string[] args) 20 { 21 //创建Book表 22 conn.Execute(@" create table Book (Id number, Name nvarchar2(100) not null),Remark nvarchar2(200)"); 23 Console.WriteLine("Created database"); 24 BOOK book = new BOOK(); 25 book.NAME = "C#本质论"; 26 book.ID = 1001; 27 string query = "INSERT INTO Book(Id,Name)VALUES(@Id,@Name)"; 28 //对对象进行操作 29 conn.Execute(query, book);//原始操作 传入sql语句和参数 30 31 ////以下是扩展中的方式 32 //直接用Insert虽然只给了部分字段,但会插入所有字段,造成数据库的默认值会被覆盖的情况 33 conn.Insert<BOOK>(new BOOK { ID = 1004, NAME = "Dapper" }); 34 conn.InsertGiven<BOOK>(new BOOK { ID = 1004, NAME = "Dapper" }); 35 //每次执行Update方法也是会更新所有字段,没赋值的字段会覆盖掉原始数据库的值 36 conn.Update<BOOK>(new BOOK { ID = 1004, NAME = "Dapper" }); 37 conn.UpdateGiven<BOOK>(new BOOK { ID = 1004, NAME = "update Dos way" }); 38 ////以下是分页查询,有一个重载 39 long longCount; 40 var sortlist=new List<ISort>(); 41 sortlist.Add(new Sort{ PropertyName="id",Ascending=true}); 42 //该方法要传入一个长整型变量供传递出查询的总量 43 var pagebook = conn.GetPageList<BOOK>(0, 10, out longCount, new BOOK { ID=1004}, sortlist); 44 //该重载不需要传入长整型变量 45 var pagebook2 = conn.GetPageList<BOOK>(0, 10, null, sortlist); 46 47 } 48 } 49 50 }
其中具体方式的实现分别如下:
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> 7 public static long InsertGiven<T>(this IDbConnection connection, T entityToInsert, IDbTransaction transaction = null, int? commandTimeout = null) where T : Entity 8 { 9 var type = typeof(T); 10 var name = GetTableName(type); 11 var mfields = entityToInsert.GetModifyFields(); 12 if (null == mfields || mfields.Count == 0) 13 return -1; 14 var sbColumnList = new StringBuilder(null); 15 SetSqlConnectTag(connection);//根据不同数据库设置标记符 SqlServer@ Oracle: 16 var keyProperties = KeyPropertiesCache(type); 17 for (var i = 0; i < mfields.Count; i++) 18 { 19 sbColumnList.AppendFormat("{0}", mfields[i].Field); 20 if (i < mfields.Count - 1) 21 sbColumnList.Append(", "); 22 } 23 var sbParameterList = new StringBuilder(null); 24 for (var i = 0; i < mfields.Count; i++) 25 { 26 sbParameterList.AppendFormat("{0}{1}", SqlConnectTag, mfields[i].Field); 27 if (i < mfields.Count - 1) 28 sbParameterList.Append(", "); 29 } 30 var adapter = GetFormatter(connection); 31 return adapter.Insert(connection, transaction, commandTimeout, name, sbColumnList.ToString(), 32 sbParameterList.ToString(), keyProperties, entityToInsert); 33 }
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> 9 public static bool UpdateGiven<T>(this IDbConnection connection, T entityToUpdate, IDbTransaction transaction = null, int? commandTimeout = null) where T : Entity 10 { 11 var proxy = entityToUpdate as IProxy; 12 if (proxy != null) 13 { 14 if (!proxy.IsDirty) return false; 15 } 16 17 var type = typeof(T); 18 19 var keyProperties = KeyPropertiesCache(type); 20 if (!keyProperties.Any()) 21 throw new ArgumentException("Entity must have at least one [Key] property"); 22 23 var name = GetTableName(type); 24 25 var mfields = entityToUpdate.GetModifyFields(); 26 if (null == mfields || mfields.Count == 0) 27 return false; 28 for (var i = 0; i < keyProperties.Count(); i++) 29 {//排除主键 30 var property = keyProperties.ElementAt(i); 31 if (mfields.Select(t => t.Field).Contains(property.Name)) 32 mfields.Remove(mfields.FirstOrDefault(t=>t.Field==property.Name)); 33 } 34 var sb = new StringBuilder(); 35 sb.AppendFormat("update {0} set ", name); 36 SetSqlConnectTag(connection);//根据不同数据库设置标记符 SqlServer@ Oracle: 37 for (var i = 0; i < mfields.Count; i++) 38 { 39 sb.AppendFormat("{0} = {2}{1}", mfields[i].Field, mfields[i].Field, SqlConnectTag); 40 if (i < mfields.Count - 1) 41 sb.AppendFormat(", "); 42 } 43 sb.Append(" where "); 44 for (var i = 0; i < keyProperties.Count(); i++) 45 { 46 var property = keyProperties.ElementAt(i); 47 sb.AppendFormat("{0} = {2}{1}", property.Name, property.Name, SqlConnectTag); 48 if (i < keyProperties.Count() - 1) 49 sb.AppendFormat(" and "); 50 } 51 var updated = connection.Execute(sb.ToString(), entityToUpdate, commandTimeout: commandTimeout, transaction: transaction); 52 return updated > 0; 53 }