对Dapper的一点改造
微软推出的ORM,
EF在我开发的项目中给我的感觉一直都是慢.优点是高度封装的底层.便于开发.
Dapper在多篇性能比较的网站中.都是名列前三.缺点是手写SQL,不便于开发.
如果能结合EF的优点和Dapper的优点.
那么此次改造相比原生Dapper是脱胎换骨的.
上图是Dapper最简单的语法.
相比ADO.NET.只增加了输出结果的序列化(LIst<T>)和输入结果的封装(List<T>).
上图是EF6.0最简单的查询.
完全封装了底层.
只要写写语法简单的lamade表达式就能完成大部分开发.
在此我将结合EF的一部分优点(lambda)和Dapper的一部分优点(性能).
做一点升级
public class DBHelper
{
//private volatile static SqlConnection _instance = null;
//private static readonly object lockHelper = new object();
//private DBHelper() { }
public static SqlConnection CreateConnection()
{
//if (_instance == null)
//{
// lock (lockHelper)
// {
// if (_instance == null)
// {
string connStr = ConfigurationManager.AppSettings["SqlConnStr"];
SqlConnection conn = new SqlConnection(connStr);
//_instance = conn;
// }
// }
//}
//string connStr = ConfigurationManager.AppSettings["SqlConnStr"];
//SqlConnection conn = new SqlConnection(connStr);
return conn;
}
/// <summary>
/// 单个数据集查询
/// </summary>
/// <param name="sql"></param>
/// <param name="parms"></param>
/// <returns></returns>
public static List<TEntity> Query<TEntity>(string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = default(int?), CommandType? commandType = default(CommandType?))
{
using (IDbConnection conn = CreateConnection())
{
return conn.Query<TEntity>(sql, param, transaction, buffered, commandTimeout, commandType).Distinct().ToList();
}
}
/// <summary>
/// 执行增、删、改方法
/// </summary>
/// <param name="sql"></param>
/// <param name="parms"></param>
/// <returns></returns>
public static int Execute(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = default(int?), CommandType? commandType = default(CommandType?))
{
using (IDbConnection conn = CreateConnection())
{
return conn.Execute(sql, param, transaction, commandTimeout, commandType);
}
}
}
以上是底层加入了垃圾回收的Dapper.
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using System.Text; namespace Microsofot.Core
{
/// <summary>
/// Lambda帮助
/// !item.IsDeleted ===> item.IsDeleted == false
/// menuIds.Contains(item.Id) + new { @Id = menuIds }
/// 请不要传递IEnumerable<TSource>因为不认识
/// </summary>
public static class LambdaHelper
{ /// <summary>
/// 查询
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="func"></param>
/// <returns></returns>
public static string Query<T>(Expression<Func<T, bool>> func) where T : class
{
string res = string.Empty;
if (func.Body is BinaryExpression)
{
BinaryExpression be = ((BinaryExpression)func.Body);
res = BinarExpressionProvider(be.Left, be.Right, be.NodeType);
}
else if (func.Body is MethodCallExpression)
{
MethodCallExpression be = ((MethodCallExpression)func.Body);
res = ExpressionRouter(func.Body);
}
else
{
res = string.Empty;
}
var a1 = func.GetType().FullName;
var a2 = a1.Split('.')[];
var a3 = a2.Split(',')[];
res = "select * from " + a3 + " where" + res;
return res;
} /// <summary>
/// 插入(支持单条和批量)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
/// <returns></returns>
public static string Insert<T>(T model)
{
var sql = "insert into " + model.GetType().Name + " values (";
var dic = GetProperties(model); for (int i = ; i < dic.Count; i++)
{
if (i == )
{
//跳过主键
continue;
} if (dic.Count - > i)
{
sql += "@" + dic[i] + ",";
} if (dic.Count - == i)
{
sql += "@" + dic[i] + ")";
}
}
return sql;
} /// <summary>
/// 修改(支持单条和批量)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
/// <returns></returns>
public static string Update<T>(T model)
{
var sql = "update " + model.GetType().Name + " set "; var dic = new Dictionary<object, object>();
if (model == null) { return null; }
PropertyInfo[] properties = model.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
if (properties.Length <= ) { return null; }
int a = ;
foreach (PropertyInfo item in properties)
{
string name = item.Name;
object value = item.GetValue(model, null);
if (item.PropertyType.IsValueType || item.PropertyType.Name.StartsWith("String"))
{
dic.Add(a, name+","+ value);
a++;
}
} for (int i = ; i < dic.Count; i++)
{
var split = dic[i].ToString().Split(',');
if (i == )
{
//跳过主键
continue;
} if (dic.Count - > i)
{
//非最后一个字段拼接sql加逗号
if (!string.IsNullOrWhiteSpace(split[]))
{
sql += split[] + "=@" + split[] + ",";
} } if (dic.Count - == i)
{
var id = dic[].ToString().Split(',');
if (!string.IsNullOrWhiteSpace(split[]))
{
sql += split[] + "=@" + split[];
} sql += " where "+ id[] + "=@" + id[];
}
}
return sql;
} /// <summary>
/// 逻辑删除(支持单条和批量)
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="model"></param>
/// <returns></returns>
public static string Delete<T>(T model)
{
var sql = "update " + model.GetType().Name + " set "; var dic = new Dictionary<object, object>();
if (model == null) { return null; }
PropertyInfo[] properties = model.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
if (properties.Length <= ) { return null; }
int a = ;
foreach (PropertyInfo item in properties)
{
string name = item.Name;
object value = item.GetValue(model, null);
if (item.PropertyType.IsValueType || item.PropertyType.Name.StartsWith("String"))
{
dic.Add(a, name + "," + value);
a++;
}
}
var id = dic[].ToString().Split(','); sql += " IsDeleted='true'";
sql += " where " + id[] + "=@" + id[]; return sql;
} /// <summary>
/// 排序
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="exp"></param>
/// <param name="desc">true顺序false倒序</param>
/// <returns></returns>
public static string Order<T>(Expression<Func<T, object>> exp,bool desc) where T : class
{
string orderby = " order by";
var res = string.Empty;
if (exp.Body is UnaryExpression)
{
UnaryExpression ue = ((UnaryExpression)exp.Body);
res = ExpressionRouter(ue.Operand).ToLower() ;
}
else
{
MemberExpression order = ((MemberExpression)exp.Body);
res = order.Member.Name.ToLower() ;
}
if (desc)
{
res = $"{orderby} '{res}'";
}
else
{
res = $"{orderby} '{res}' desc";
} return res;
} private static string GetValueStringByType(object oj)
{
if (oj == null)
{
return "null";
}
else if (oj is ValueType)
{
return oj.ToString();
}
else if (oj is string || oj is DateTime || oj is char)
{
return string.Format("'{0}'", oj.ToString());
}
else
{
return string.Format("'{0}'", oj.ToString());
}
} private static string BinarExpressionProvider(Expression left, Expression right, ExpressionType type)
{
string sb = "(";
//先处理左边
string reLeftStr = ExpressionRouter(left);
sb += reLeftStr; sb += ExpressionTypeCast(type); //再处理右边
string tmpStr = ExpressionRouter(right);
if (tmpStr == "null")
{
if (sb.EndsWith(" ="))
{
sb = sb.Substring(, sb.Length - ) + " is null";
}
else if (sb.EndsWith("<>"))
{
sb = sb.Substring(, sb.Length - ) + " is not null";
}
}
else
{
//添加参数
sb += tmpStr;
} return sb += ")";
} private static string ExpressionRouter(Expression exp)
{
string sb = string.Empty; if (exp is BinaryExpression)
{
BinaryExpression be = ((BinaryExpression)exp);
return BinarExpressionProvider(be.Left, be.Right, be.NodeType);
}
else if (exp is MemberExpression)
{
MemberExpression me = ((MemberExpression)exp);
if (!exp.ToString().StartsWith("value"))
{
return me.Member.Name;
}
else
{
var result = Expression.Lambda(exp).Compile().DynamicInvoke();
if (result == null)
{
return "null";
}
else if (result is ValueType)
{
//return Convert.ToBoolean(result) ? "1" : "0";
return Convert.ToString(result);
}
else if (result is string || result is DateTime || result is char)
{
return string.Format("'{0}'", result.ToString());
}
else if (result is int[])
{
var rl = result as int[];
StringBuilder sbIntStr = new StringBuilder();
sbIntStr.Append("(");
foreach (var r in rl)
{
if (sbIntStr.Length == )
sbIntStr.Append(Convert.ToString(r));
else
sbIntStr.Append("," + Convert.ToString(r));
}
sbIntStr.Append(")");
return sbIntStr.ToString();
}
else if (result is string[])
{
var rl = result as string[];
StringBuilder sbIntStr = new StringBuilder();
sbIntStr.Append("(");
foreach (var r in rl)
{
if (sbIntStr.Length == )
sbIntStr.Append("'" + r + "'");
else
sbIntStr.Append(",'" + r + "'");
}
sbIntStr.Append(")");
return sbIntStr.ToString();
}
}
}
else if (exp is NewArrayExpression)
{
NewArrayExpression ae = ((NewArrayExpression)exp);
StringBuilder tmpstr = new StringBuilder();
foreach (Expression ex in ae.Expressions)
{
tmpstr.Append(ExpressionRouter(ex));
tmpstr.Append(",");
}
//添加参数 return tmpstr.ToString(, tmpstr.Length - );
}
else if (exp is MethodCallExpression)
{
MethodCallExpression mce = (MethodCallExpression)exp; string value = ExpressionRouter(mce.Arguments[]).Replace("'", "");
string[] exps = mce.ToString().Split(new char[] { '.' });
string fieldName = exps[exps.Length-].Split(new char[] { ')' })[]; if (mce.Method.Name == "In")
return string.Format("{0} In ({1})", ExpressionRouter(mce.Arguments[]), ExpressionRouter(mce.Arguments[]));
else if (mce.Method.Name == "NotIn")
return string.Format("{0} Not In ({1})", ExpressionRouter(mce.Arguments[]), ExpressionRouter(mce.Arguments[]));
else if (mce.Method.Name == "Contains")
return fieldName + " in @" + value;
else if (mce.Method.Name == "StartsWith")
return fieldName + " like '" + value + "%'";
else if (mce.Method.Name == "EndsWith")
return fieldName + " like '%" + value + "'";
}
else if (exp is ConstantExpression)
{
ConstantExpression ce = ((ConstantExpression)exp);
if (ce.Value == null)
{
return "null";
}
else if (ce.Value is ValueType)
{
//return Convert.ToBoolean(ce.Value) ? "1" : "0";
return Convert.ToString("'"+ce.Value+"'");
}
else if (ce.Value is string || ce.Value is DateTime || ce.Value is char)
{
return string.Format("'{0}'", Convert.ToString(ce.Value));
} //对数值进行参数附加
}
else if (exp is UnaryExpression)
{
UnaryExpression ue = ((UnaryExpression)exp); return ExpressionRouter(ue.Operand);
}
return null;
} private static string ExpressionTypeCast(ExpressionType type)
{
switch (type)
{
case ExpressionType.And:
case ExpressionType.AndAlso:
return " AND "; case ExpressionType.Equal:
return " ="; case ExpressionType.GreaterThan:
return " >"; case ExpressionType.GreaterThanOrEqual:
return ">="; case ExpressionType.LessThan:
return "<"; case ExpressionType.LessThanOrEqual:
return "<="; case ExpressionType.NotEqual:
return "<>"; case ExpressionType.Or:
case ExpressionType.OrElse:
return " Or "; case ExpressionType.Add:
case ExpressionType.AddChecked:
return "+"; case ExpressionType.Subtract:
case ExpressionType.SubtractChecked:
return "-"; case ExpressionType.Divide:
return "/"; case ExpressionType.Multiply:
case ExpressionType.MultiplyChecked:
return "*"; default:
return null;
}
} /// <summary>
/// 读取实体的属性字段和值
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="t"></param>
/// <returns></returns>
private static Dictionary<object, object> GetProperties<T>(T t)
{
var ret = new Dictionary<object, object>();
if (t == null) { return null; }
PropertyInfo[] properties = t.GetType().GetProperties(BindingFlags.Instance | BindingFlags.Public);
if (properties.Length <= ) { return null; }
int i = ;
foreach (PropertyInfo item in properties)
{
string name = item.Name;
object value = item.GetValue(t, null);
if (item.PropertyType.IsValueType || item.PropertyType.Name.StartsWith("String"))
{
ret.Add(i, name);
i++;
}
}
return ret;
} }
}
以上是将Lambda转换为Sql的帮助类
using Microsofot.Core;
using Microsoft.Data;
using Microsoft.Entity;
using Microsoft.Service.Interface;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Linq.Expressions; namespace Microsoft.Service.Service
{
/// <summary>
/// 访问服务
/// </summary>
public class PageViewService: IPageViewService
{
/// <summary>
/// 查询
/// </summary>
/// <param name="exp"></param>
/// <returns></returns>
public List<PageView> Query(Expression<Func<PageView, bool>> exp, Expression<Func<PageView, object>> order, bool desc, object param = null)
{
List<PageView> result = null;
if (exp != null)
{
var sql = LambdaHelper.Query(exp) + LambdaHelper.Order(order, desc);
if (!string.IsNullOrWhiteSpace(sql))
{
result = DapperManager.Query<PageView>(sql,param).ToList();
LogHelper.Info("PageViewService.Query:" + result.Count);
}
}
return result;
} /// <summary>
/// 单条插入
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int Insert(PageView model)
{
int result = -;
if (model != null)
{
string sql = LambdaHelper.Insert(model);
result = DapperManager.Execute(sql, model, null, null, CommandType.Text);
LogHelper.Info("PageViewService.Insert:" + result);
}
return result;
} /// <summary>
/// 批量插入
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int Insert(List<PageView> model)
{
int result = -;
if (model != null)
{
string sql = LambdaHelper.Insert(model.Last());
result = DapperManager.Execute(sql, model, null, null, CommandType.Text);
LogHelper.Info("PageViewService.Insert:" + result);
}
return result;
} /// <summary>
/// 单条修改
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int Update(PageView model)
{
int result = -;
if (model != null)
{
string sql = LambdaHelper.Update(model);
result = DapperManager.Execute(sql, model, null, null, CommandType.Text);
LogHelper.Info("PageViewService.Update:" + result);
}
return result;
} /// <summary>
/// 多条修改
/// </summary>
/// <param name="model"></param>
/// <returns></returns>
public int Update(List<PageView> model)
{
int result = -;
if (model != null)
{
string sql = LambdaHelper.Update(model.Last());
result = DapperManager.Execute(sql, model, null, null, CommandType.Text);
LogHelper.Info("PageViewService.Update:" + result);
}
return result;
} /// <summary>
/// 单条删除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public int Delete(PageView model)
{
int result = -;
if (model != null)
{
string sql = LambdaHelper.Delete(model);
result = DapperManager.Execute(sql, model, null, null, CommandType.Text);
LogHelper.Info("PageViewService.Delete:" + result);
}
return result;
} /// <summary>
/// 多条删除
/// </summary>
/// <param name="id"></param>
/// <returns></returns>
public int Delete(List<PageView> model)
{
int result = -;
if (model != null)
{
string sql = LambdaHelper.Delete(model.Last());
result = DapperManager.Execute(sql, model, null, null, CommandType.Text);
LogHelper.Info("PageViewService.Delete:" + result);
}
return result;
} /// <summary>
/// 原生Dapper查询
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="sql"></param>
/// <param name="param"></param>
/// <param name="transaction"></param>
/// <param name="buffered"></param>
/// <param name="commandTimeout"></param>
/// <param name="commandType"></param>
/// <returns></returns>
public List<T> Query<T>(string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = default(int?), CommandType? commandType = default(CommandType?))
{
return DapperManager.Query<T>(sql, param, transaction, buffered, commandTimeout, commandType).ToList();
}
/// <summary>
/// 原生Dapper增、删、改、存储过程方法
/// </summary>
/// <param name="sql"></param>
/// <param name="parms"></param>
/// <returns></returns>
public int Execute(string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = default(int?), CommandType? commandType = default(CommandType?))
{
return DapperManager.Execute(sql, param, transaction, commandTimeout, commandType);
}
}
}
以上调用案例就和EF很像了.
但是底层还是保持着Dapper的模式.
至于性能比之原生Dapper或者EF6.0.
有空的各位就可以试试了
对Dapper的一点改造的更多相关文章
- 【UVA 10307 Killing Aliens in Borg Maze】最小生成树, kruscal, bfs
题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=20846 POJ 3026是同样的题,但是内存要求比较严格,并是没有 ...
- 一步一步从原理跟我学邮件收取及发送 11.完整的发送示例与go语言
经过了这个系列的前几篇文章的学习,现在要写出一个完整的 smtp 邮件发送过程简直易如反掌. 例如我们可以轻松地写出以下的纯 C 语言代码(引用的其他C语言文件请看文末的 github 地址): ...
- 微信小程序开发06-一个业务页面的完成
前言 接上文:微信小程序开发05-日历组件的实现 github地址:https://github.com/yexiaochai/wxdemo 这里来说一说我们的理念,我们也学习小程序开发有一周多了,从 ...
- 【golang-GUI开发】Qt项目的打包发布
这是本系列的第三篇文章,前两篇我们讲了qt的安装和编译,今天我们讲一讲程序的打包. 好像我们现在都没怎么讲到qt的使用,因为想要放开手脚写代码,一些基础是要打牢的. 不过请放心,下一篇文章开始我们就会 ...
- 论文阅读笔记三十六:Mask R-CNN(CVPR2017)
论文源址:https://arxiv.org/pdf/1703.06870.pdf 开源代码:https://github.com/matterport/Mask_RCNN 摘要 Mask R-CNN ...
- 从0移植uboot (四) _点亮调试LED
这一节主要讨论1个问题:点灯.点灯是实际开发中,特别是裸板开发中常见的调试手段,相当于主机开发中漫天飞舞的printf/printk.为了追踪程序的现场执行情况,很多时候我们都使用点一个灯的方法来进行 ...
- 我所理解的event loop
灵魂三问 JS为什么是单线程的 我们都知道,JS是单线程的语言,那为什么呢?我的理解是JS设计之初就是为了在浏览器端完成DOM操作和一些简单交互的,既然涉及到DOM操作如果是多线程就会带来复杂的同步问 ...
- JS — 对象的基本操作
JS面向对象系列教程 — 对象的基本操作 面向对象概述  面向对象(Object Oriented)简称OO,它是一种编程思维,用于指导我们如何应对各种复杂的开发场景. 这里说的对象(Object) ...
- JS面向对象系列教程 — 对象的基本操作
面向对象概述  面向对象(Object Oriented)简称OO,它是一种编程思维,用于指导我们如何应对各种复杂的开发场景. 这里说的对象(Object),意思就是事物,在面向对象的思维中,它将一 ...
随机推荐
- JSON格式化以及转化为Entity事项
其实JSON在eclipse里面就可以自动化,不需要再联网去进行格式化: 然后通过http://www.bejson.com/java2pojo/ 即可实现json转java 但是要注意:从str ...
- Python 修改ha配置文件
任务要求: 1.用户输入字符串 {"backend": "test.oldboy.org","record":{"server&q ...
- Azure VM复制
目前Azure上复制VM可以有多种方法: 1 创建User Image,可以快速复制多台VM,但目前托管磁盘只支持Generalized的模式,需要对User和配置进行重置. 2 从VHD或托管磁盘复 ...
- ov2640数据
问题部分解决,数据错误的原因是太快了.将0x11->3f 0xd3->7f 哈哈 问题解决 直接降低7670输出频率 调0x11到最大分频比 现在能完整抓拍QVGA的图像 不过就是采集速 ...
- canvas绘制简单图形
canvas绘图篇: canvas绘制矩形: <!DOCTYPE html> <html> <head lang="en"> <meta ...
- JS:Window
ylbtech-JS:Window 1.返回顶部 1.happy.js ; (function () { var happyUi = { initHappy: function (type) { ut ...
- java--构造器与static
原本无显示编码构造器,则有一个默认的隐式(隐藏的无参构造器),但是,当显示指定了构造器,则这个默认隐式的构造器将不存在,比如此时无法new无参的构造器(除非显示地编写声明无参的构造函数). 如果子类构 ...
- 自定义数据校验(4)---demo3---bai
工具类:CharUtil package com.etc.util; import java.util.regex.Pattern; public class CharUtil { public st ...
- appium_python 实现手势密码
直接上代码吧: from appium.webdriver.common.touch_action import TouchAction from driver import AppiumTest # ...
- Eclipse: “The import java.io cannot be resolved”
检查一下选项: 重点看jdk的绑定 43down voteaccepted Check your Eclipse preferences: Java -> Installed JREs. The ...