基于轻量级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
三.举栗子
这里用上面的方法来简单的测试一下。
using System;
using System.Collections.Generic;
using System.Data;
using System.Data.SqlClient;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Dapper;
using System.Data.OracleClient;
using Dapper.Contrib.Extensions;
using Dapper.Contrib;
using Dapper.Model;
namespace ConsoleTest1
{
class Program
{
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=*;");
static void Main(string[] args)
{
//创建Book表
conn.Execute(@" create table Book (Id number, Name nvarchar2(100) not null),Remark nvarchar2(200)");
Console.WriteLine("Created database");
BOOK book = new BOOK();
book.NAME = "C#本质论";
book.ID = ;
string query = "INSERT INTO Book(Id,Name)VALUES(@Id,@Name)";
//对对象进行操作
conn.Execute(query, book);//原始操作 传入sql语句和参数 ////以下是扩展中的方式
//直接用Insert虽然只给了部分字段,但会插入所有字段,造成数据库的默认值会被覆盖的情况
conn.Insert<BOOK>(new BOOK { ID = , NAME = "Dapper" });
conn.InsertGiven<BOOK>(new BOOK { ID = , NAME = "Dapper" });
//每次执行Update方法也是会更新所有字段,没赋值的字段会覆盖掉原始数据库的值
conn.Update<BOOK>(new BOOK { ID = , NAME = "Dapper" });
conn.UpdateGiven<BOOK>(new BOOK { ID = , NAME = "update Dos way" });
////以下是分页查询,有一个重载
long longCount;
var sortlist=new List<ISort>();
sortlist.Add(new Sort{ PropertyName="id",Ascending=true});
//该方法要传入一个长整型变量供传递出查询的总量
var pagebook = conn.GetPageList<BOOK>(, , out longCount, new BOOK { ID=}, sortlist);
//该重载不需要传入长整型变量
var pagebook2 = conn.GetPageList<BOOK>(, , null, sortlist); }
} }
其中具体方式的实现分别如下:
/// <summary>
/// Inserts an entity into table "Ts" and returns identity id.(Insert the given fields)
/// </summary>
/// <param name="connection">Open SqlConnection</param>
/// <param name="entityToInsert">Entity to insert</param>
/// <returns>Identity of inserted entity</returns>
public static long InsertGiven<T>(this IDbConnection connection, T entityToInsert, IDbTransaction transaction = null, int? commandTimeout = null) where T : Entity
{
var type = typeof(T);
var name = GetTableName(type);
var mfields = entityToInsert.GetModifyFields();
if (null == mfields || mfields.Count == )
return -;
var sbColumnList = new StringBuilder(null);
SetSqlConnectTag(connection);//根据不同数据库设置标记符 SqlServer@ Oracle:
var keyProperties = KeyPropertiesCache(type);
for (var i = ; i < mfields.Count; i++)
{
sbColumnList.AppendFormat("{0}", mfields[i].Field);
if (i < mfields.Count - )
sbColumnList.Append(", ");
}
var sbParameterList = new StringBuilder(null);
for (var i = ; i < mfields.Count; i++)
{
sbParameterList.AppendFormat("{0}{1}", SqlConnectTag, mfields[i].Field);
if (i < mfields.Count - )
sbParameterList.Append(", ");
}
var adapter = GetFormatter(connection);
return adapter.Insert(connection, transaction, commandTimeout, name, sbColumnList.ToString(),
sbParameterList.ToString(), keyProperties, entityToInsert);
}
InsertGiven
/// <summary>
/// Updates entity in table "Ts", checks if the entity is modified if the entity is tracked by the Get() extension.
/// update the given fileds
/// </summary>
/// <typeparam name="T">Type to be updated</typeparam>
/// <param name="connection">Open SqlConnection</param>
/// <param name="entityToUpdate">Entity to be updated</param>
/// <returns>true if updated, false if not found or not modified (tracked entities)</returns>
public static bool UpdateGiven<T>(this IDbConnection connection, T entityToUpdate, IDbTransaction transaction = null, int? commandTimeout = null) where T : Entity
{
var proxy = entityToUpdate as IProxy;
if (proxy != null)
{
if (!proxy.IsDirty) return false;
} var type = typeof(T); var keyProperties = KeyPropertiesCache(type);
if (!keyProperties.Any())
throw new ArgumentException("Entity must have at least one [Key] property"); var name = GetTableName(type); var mfields = entityToUpdate.GetModifyFields();
if (null == mfields || mfields.Count == )
return false;
for (var i = ; i < keyProperties.Count(); i++)
{//排除主键
var property = keyProperties.ElementAt(i);
if (mfields.Select(t => t.Field).Contains(property.Name))
mfields.Remove(mfields.FirstOrDefault(t=>t.Field==property.Name));
}
var sb = new StringBuilder();
sb.AppendFormat("update {0} set ", name);
SetSqlConnectTag(connection);//根据不同数据库设置标记符 SqlServer@ Oracle:
for (var i = ; i < mfields.Count; i++)
{
sb.AppendFormat("{0} = {2}{1}", mfields[i].Field, mfields[i].Field, SqlConnectTag);
if (i < mfields.Count - )
sb.AppendFormat(", ");
}
sb.Append(" where ");
for (var i = ; i < keyProperties.Count(); i++)
{
var property = keyProperties.ElementAt(i);
sb.AppendFormat("{0} = {2}{1}", property.Name, property.Name, SqlConnectTag);
if (i < keyProperties.Count() - )
sb.AppendFormat(" and ");
}
var updated = connection.Execute(sb.ToString(), entityToUpdate, commandTimeout: commandTimeout, transaction: transaction);
return updated > ;
}
UpdateGiven
/// <summary>
/// Paging
/// </summary>
/// <typeparam name="T">传入实体类型</typeparam>
/// <param name="connection">此连接</param>
/// <param name="pageIndex">第几页:0为第一页开始</param>
/// <param name="pageSize">每页数量</param>
/// <param name="allRowsCount">返回满足条件总量</param>
/// <param name="entityToPredicate">条件:实体传入</param>
/// <param name="sort">排序条件:ISort列表方式传入</param>
/// <param name="buffered">是否缓存</param>
/// <returns></returns>
public static IEnumerable<T> GetPageList<T>(this IDbConnection connection, int pageIndex, int pageSize, out long allRowsCount,
T entityToPredicate = null, IList<ISort> sort = null, bool buffered = true) where T : Entity
{
DynamicParameters dynamicParameters = new DynamicParameters();
var type = typeof(T);
SetSqlConnectTag(connection);//根据不同数据库设置标记符 SqlServer@ Oracle:
var keys = KeyPropertiesCache(type);
if (keys.Count() > )
throw new DataException("Get<T> only supports an entity with a single [Key] property");
if (!keys.Any())
throw new DataException("Get<T> only supports en entity with a [Key] property"); var onlyKey = keys.First();
StringBuilder innersql = new StringBuilder(string.Format("SELECT * FROM {0}",
GetTableName(type)));
if (entityToPredicate != null)
{
var mfields = entityToPredicate.GetModifyFields();
innersql.Append(" where ");
for (var i = ; i < mfields.Count; i++)
{
innersql.AppendFormat("{0} = {2}{1}", mfields[i].Field, mfields[i].Field, SqlConnectTag);
if (i < mfields.Count - )
innersql.AppendFormat(", ");
dynamicParameters.Add(mfields[i].Field, mfields[i].NewValue);
}
}
if (sort != null && sort.Any())
{
innersql.Append(" ORDER BY ")
.Append(sort.Select(s => s.PropertyName + (s.Ascending ? " ASC" : " DESC")).AppendStrings());
}
allRowsCount = connection.Query(innersql.ToString(), entityToPredicate).Count();
Dictionary<string, object> parameters = new Dictionary<string, object>();
string sql = GetFormatter(connection).GetPagingSql(innersql.ToString(), pageIndex, pageSize, parameters);
foreach (var parameter in parameters)
{
dynamicParameters.Add(parameter.Key, parameter.Value);
}
return connection.Query<T>(sql, dynamicParameters);
}
下面我们来调试一下来看看Insert和InsertGiven、Update和UpdateGiven的区别吧
////以下是扩展中的方式
//直接用Insert虽然只给了部分字段,但会插入所有字段,造成数据库的默认值会被覆盖的情况
conn.Insert<BOOK>(new BOOK { ID = , NAME = "Dapper" });
conn.InsertGiven<BOOK>(new BOOK { ID = , NAME = "Dapper" });
//每次执行Update方法也是会更新所有字段,没赋值的字段会覆盖掉原始数据库的值
conn.Update<BOOK>(new BOOK { ID = , NAME = "Dapper" });
conn.UpdateGiven<BOOK>(new BOOK { ID = , NAME = "update Dos way" });
Insert生成的sql语句:
InsertGiven生成的sql语句:
Update生成的sql语句:
UpdateGiven生成的sql语句:
想必扩展的方法个中缘由就一清二楚了。
四.实体类生成
其中BOOK实体类如何生成?这里借鉴了DOS生成实体类工具,并新增了一个模板文件->生成实体类_Dapper_模板文件.tpl
打开DOSTOOL的Debug文件,将其放入模板文件中,重新打开DOSTOOL文件便可看见新增了一个模板,选择其模板,生成代码即可。
以上。
基于轻量级ORM框架Dapper的扩展说明的更多相关文章
- .NET轻量级ORM框架Dapper入门精通
一.课程介绍 本次分享课程包含两个部分<.NET轻量级ORM框架Dapper修炼手册>和<.NET轻量级ORM框架Dapper葵花宝典>,阿笨将带领大家一起领略轻量级ORM框架 ...
- 轻量级ORM框架Dapper应用一:Dapper安装
一.Dapper简介 Dapper是一款轻量级ORM框架,为解决网站访问流量极高而产生的性能问题而构造,主要通过执行TSQL表达式而实现数据库的CQRS. 如果你在项目中遇到性能访问问题,选择Dapp ...
- .NET 轻量级 ORM 框架 - Dapper 介绍
Dapper简单介绍: Dapper is a single file you can drop in to your project that will extend your IDbConnect ...
- 轻量级ORM框架 Dapper快速学习
好在有师兄师姐一起带着做,所以开始没那么困难,但是由于大学涉猎范围有限,往往有很尴尬的时候,不懂构造方法重载,去“请教”,本来以为师兄会帮忙写好,结果“我念,你来写”,被深深的激励了一把,后来就早出晚 ...
- 轻量级ORM框架Dapper应用八:使用Dapper实现DTO
一.什么是DTO 先来看看百度百科的解释: 数据传输对象(DTO)(Data Transfer Object),是一种设计模式之间传输数据的软件应用系统.数据传输目标往往是数据访问对象从数据库中检索数 ...
- 轻量级ORM框架Dapper应用六:Dapper支持存储过程
在Entity Framework中讲解了EF如何支持存储过程,同样,Dapper也支持存储过程,只需要在Query()方法的CommandType中标记使用的是存储过程就可以了.在Users表上面创 ...
- 轻量级ORM框架Dapper应用五:使用Dapper实现Join操作
在这篇文章中,讲解如何使用Dapper使用Inner join的操作 1.新创建两张表:Users表和Product表 Users表定义如下: CREATE TABLE [dbo].[Users]( ...
- 轻量级ORM框架Dapper应用四:使用Dapper返回多个结果集
使用Dapper的QueryMultiple方法可以一次执行多条SQL语句,返回多个结果集,代码如下 using System; using System.Collections.Generic; u ...
- 轻量级ORM框架Dapper应用三:使用Dapper实现In操作
IN 操作符允许我们在 WHERE 子句中规定多个值. 本篇文章中,还是使用和上篇文章中同样的实体类和数据库,Dapper使用in操作符的代码如下: using System; using Syste ...
随机推荐
- xdu_1064:Desolator in RA2
问题转化为,单个面积*2-交面积.下面求交面积.把直角坐标系中全部转90°,每个方块的坐标都做相应变化,这样会发现新的坐标系中空出了一部分方块,找规律发现,若求交矩形包含的方框数,其中恰好一半是前面空 ...
- 没有绝对安全的系统:写在AES 256破解之后
NULL 在理论上,理论和实践是一致的.在实践中,呵呵. ——(应该是)爱因斯坦(说的) (INFO:本文中不会出现公式,请放心阅读) AES 256被破解了? 对于TLNR(Too Long, No ...
- plsql 数据迁移——导出表结构,表数据,表序号
场景:项目开发完之后要部署在不同的环境进行测试,这时候就需要将数据库中的表结构,序号,数据进行迁移,这时候就需要能够熟练的使用plsql. 问题: 导出的表结构,在另一个数据库中无法导入 部分表的数据 ...
- (转)Java线程:线程的同步与锁
Java线程:线程的同步与锁 一.同步问题提出 线程的同步是为了防止多个线程访问一个数据对象时,对数据造成的破坏. 例如:两个线程ThreadA.ThreadB都操作同一个对象Fo ...
- linux下使用scp远程传输自动输入密码
由于需要将A服务器的文件 远程传输到B服务器 但是scp命令每次都要手动输入密码 这样脚本执行太繁琐,所以讲A服务器和B服务器互信即可,具体操作如下: 首先在A服务器配置: mkdir -p ~/.s ...
- PHP执行linux命令mkdir权限问题
在linux系统中,root帐号执行php命令: mkdir('test', 0777); 结果文件的权限依然为: drwxr-xr-x 2 root root Jul 27 19:30 test ...
- [NOI2005] 维护数列
[NOI2005] 维护数列 题目 传送门 请写一个程序,要求维护一个数列,支持以下 6 种操作:(请注意,格式栏 中的下划线‘ _ ’表示实际输入文件中的空格) 操作编号 输入文件中的格式 说明 1 ...
- RedHat Enterprise Linu…
RedHat Enterprise Linux 6.4 使用Centos 6 的yum 源问题 2015.04.09 一.问题描述 有时在使用RedHat 系统进行安装某些软件时,会出现如下提示: T ...
- rocketmq client for c#
基于ikvm的rocketmq的c#客户端,由于阿里对c#不敏感,对这方面的东西缺少.因为工作需要弄了一个,分享给大家 https://github.com/franknew/RocketMQ-Cli ...
- git版本控制 for window安装和命令行使用
Git 安装配置 Windows 平台上安装 在 Windows 平台上安装 Git 同样轻松,有个叫做 msysGit 的项目提供了安装包,可以到 GitHub 的页面上下载 exe 安装文件并运行 ...