基于轻量级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=192.168.1.79)(PORT=1521)))(CONNECT_DATA=(service_name =acid)));Persist Security Info=True;User ID=hl_platform; Password=intest;");
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);//根据不同数据库设置标记符 [email protected] 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         }

InsertGiven

 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);//根据不同数据库设置标记符 [email protected] 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         }

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>
13         public static IEnumerable<T> GetPageList<T>(this IDbConnection connection, int pageIndex, int pageSize, out long allRowsCount,
14         T entityToPredicate = null, IList<ISort> sort = null, bool buffered = true) where T : Entity
15         {
16             DynamicParameters dynamicParameters = new DynamicParameters();
17             var type = typeof(T);
18             SetSqlConnectTag(connection);//根据不同数据库设置标记符 [email protected] Oracle:
19             var keys = KeyPropertiesCache(type);
20             if (keys.Count() > 1)
21                 throw new DataException("Get<T> only supports an entity with a single [Key] property");
22             if (!keys.Any())
23                 throw new DataException("Get<T> only supports en entity with a [Key] property");
24
25             var onlyKey = keys.First();
26             StringBuilder innersql = new StringBuilder(string.Format("SELECT * FROM {0}",
27                 GetTableName(type)));
28             if (entityToPredicate != null)
29             {
30                 var mfields = entityToPredicate.GetModifyFields();
31                 innersql.Append(" where ");
32                 for (var i = 0; i < mfields.Count; i++)
33                 {
34                     innersql.AppendFormat("{0} = {2}{1}", mfields[i].Field, mfields[i].Field, SqlConnectTag);
35                     if (i < mfields.Count - 1)
36                         innersql.AppendFormat(", ");
37                     dynamicParameters.Add(mfields[i].Field, mfields[i].NewValue);
38                 }
39             }
40             if (sort != null && sort.Any())
41             {
42                 innersql.Append(" ORDER BY ")
43                     .Append(sort.Select(s => s.PropertyName + (s.Ascending ? " ASC" : " DESC")).AppendStrings());
44             }
45             allRowsCount = connection.Query(innersql.ToString(), entityToPredicate).Count();
46             Dictionary<string, object> parameters = new Dictionary<string, object>();
47             string sql = GetFormatter(connection).GetPagingSql(innersql.ToString(), pageIndex, pageSize, parameters);
48             foreach (var parameter in parameters)
49             {
50                 dynamicParameters.Add(parameter.Key, parameter.Value);
51             }
52             return connection.Query<T>(sql, dynamicParameters);
53         }

下面我们来调试一下来看看Insert和InsertGiven、Update和UpdateGiven的区别吧

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

Insert生成的sql语句:

InsertGiven生成的sql语句:

Update生成的sql语句:

UpdateGiven生成的sql语句:

想必扩展的方法个中缘由就一清二楚了。

四.实体类生成

其中BOOK实体类如何生成?这里借鉴了DOS生成实体类工具,并新增了一个模板文件->生成实体类_Dapper_模板文件.tpl

打开DOSTOOL的Debug文件,将其放入模板文件中,重新打开DOSTOOL文件便可看见新增了一个模板,选择其模板,生成代码即可。

以上。

时间: 2024-10-13 01:12:44

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

.NET轻量级ORM框架Dapper入门精通

一.课程介绍 本次分享课程包含两个部分<.NET轻量级ORM框架Dapper修炼手册>和<.NET轻量级ORM框架Dapper葵花宝典>,阿笨将带领大家一起领略轻量级ORM框架Dapper的魅力. 本次分享课程适合人群范围: 一.<.NET轻量级ORM框架Dapper修炼手册>适合人群如下: 1.我是一个新手,主要工作面向的是MS SQL Server数据库,那么选择修炼手册一定没错. 2.对Dapper从没有过了解或者了解不全面的同学,想通过学习进一步提升对Dappe

.NET轻量级ORM框架Dapper修炼手册

一.摘要 1.1.为什么叫本次的分享课叫<修炼手册>? 阿笨希望本次的分享课中涉及覆盖的一些小技巧.小技能给您带来一些帮助.希望您在日后工作中把它作为一本实际技能手册进行储备,以备不时之需,一旦当手头遇到与Dapper修炼手册中相似用法的地方和场景,可以直接拿来进行翻阅并灵活的运用到项目中.最后阿笨建议您可以根据自己在工作中碰到的不同的使用场景,不断的完善此本修炼手册. 废话不多说,直接上干货,我们不生产干货,我们只是干货的搬运工. 四.涉及覆盖的知识点 1.C# Linq To Xml技术.

轻量级ORM框架 Dapper快速学习

好在有师兄师姐一起带着做,所以开始没那么困难,但是由于大学涉猎范围有限,往往有很尴尬的时候,不懂构造方法重载,去“请教”,本来以为师兄会帮忙写好,结果“我念,你来写”,被深深的激励了一把,后来就早出晚归补习练习,java有所成长.实验室的项目是以Elipse插件形式给某研究所做一个工具,所以当时对Eclipse的了解很是深入,用到GEF图形编辑框架,SWT来做界面.自己用XML做存储来实现复制粘贴,还第一次用到了设计模式,visitor.实验室的节奏一直是“时间紧,任务重,成败在此一举”的节奏,

.NET轻量级ORM组件Dapper葵花宝典

一.摘要 为什么取名叫<葵花宝典>? 从行走江湖的世界角度来讲您可以理解为一本"武功秘籍",站在我们IT编程的世界角度应该叫"开发宝典". 如果您在工作中主要接触的是操作MySQL数据库,但您又想学习和了解.NET轻量级ORM框架Dapper,那么就请跟着阿笨一起学习本次的分享课<.NET轻量级ORM框架Dapper葵花宝典>.Let's Go,Do It ,Dapper For MySQL! 废话不多说,直接上干货,我们不生产干货,我们只是

分享自己写的基于Dapper的轻量级ORM框架~

1.说明 本项目是一个使用.NET Standard 2.0开发的,基于 Dapper 的轻量级 ORM 框架,包含基本的CRUD以及根据表达式进行一些操作的方法,目前只针对单表,不包含多表连接操作. github:https://github.com/iamoldli/NetSql 2.使用方法 2.2.安装 Install-Package NetSql 2.2.创建实体 创建Article实体类,继承EntityBase public class Article : EntityBase {

轻量级ORM框架初探-Dapper与PetaPoco的基本使用

一.EntityFramework EF是传统的ORM框架,也是一个比较重量级的ORM框架.这里仍然使用EF的原因在于为了突出轻量级ORM框架的性能,所谓有对比才有更优的选择. 1.1 准备一张数据库表 (1)For MSSQL CREATE TABLE [dbo].[Posts] ( [Id] INT NOT NULL PRIMARY KEY IDENTITY, [CategoryId] INT NOT NULL, [Slug] VARCHAR(120) NOT NULL, [Title] N

.NET轻量级ORM组件Dapper修炼手册

一.摘要 1.1.为什么叫本次的分享课叫<修炼手册>? 阿笨希望本次的分享课中涉及覆盖的一些小技巧.小技能给您带来一些帮助.希望您在日后工作中把它作为一本实际技能手册进行储备,以备不时之需,一旦当手头遇到与Dapper修炼手册中相似用法的地方和场景,可以直接拿来进行翻阅并灵活的运用到项目中.最后阿笨建议您可以根据自己在工作中碰到的不同的使用场景,不断的完善此本修炼手册. 废话不多说,直接上干货,我们不生产干货,我们只是干货的搬运工. 四.涉及覆盖的知识点 1.C# Linq To Xml技术.

c# 轻量级ORM框架 实现(一)

发布一个自己写的一个轻量级ORM框架,本框架设计期初基于三层架构.所以从命名上来看,了解三层的朋友会很好理解. 设计该框架的目的:不想重复的写增删改查,把精力放到功能实现上. 发布改框架的原因:希望给初学者一个参考,希望能给予好的建议,给自己一个展示机会. 在我开始之前,先说明一下,我对"软件工程学"概念东西几乎不通,最高文化程度:初二,所以不喜勿喷. 开始我的orm设计最底层 最底层的是一个DalBase,它是一个抽象的,实现了增删改查的基本操作. 它既然是一个抽象的,那么它的内部就

c# 轻量级 ORM 框架 之 DBHelper 实现 (三)

周末了比较清闲,把自己的orm框架整理了下,开源了. 已经做出来的东西通常感觉有些简单,一些新手或许听到"框架"一类的词觉得有些"高深",简单来说orm就是把ado的封装. 在介绍这个框架的第一篇博文,已经把DalBase介绍了一下设计思路,本篇的DBHelper对象也是给dalBase来用的,可以说框架的所有定义对象都是为了它. 这里起名叫DBHelper,因为我也是从写SQLHelper开始的,DBHelper只不过是所有类型对ado操作的各种方法的封装,所以本