wns9778.com_威尼斯wns.9778官网

热门关键词: wns9778.com,威尼斯wns.9778官网
wns9778.com > 计算机教程 > 对Dapper的一点改造

原标题:对Dapper的一点改造

浏览次数:95 时间:2019-05-10

微软推出的ORM,EF在我开发的项目中给我的感觉一直都是慢.优点是高度封装的底层.便于开发.Dapper在多篇性能比较的网站中.都是名列前三.缺点是手写SQL,不便于开发.如果能结合EF的优点和Dapper的优点.那么此次改造相比原生Dapper是脱胎换骨的.

图片 1

上图是Dapper最简单的语法.相比ADO.NET.只增加了输出结果的序列化(LIst<T>)和输入结果的封装(List<T>).

图片 2

上图是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('.')[6];
var a3 = a2.Split(',')[0];
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 = 0; i < dic.Count; i  )
{
if (i == 4)
{
//跳过主键
continue;
}

if (dic.Count - 1 > i)
{
sql  = "@"   dic[i]   ",";
}

if (dic.Count - 1 == 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 <= 0) { return null; }
int a = 0;
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 = 0; i < dic.Count; i  )
{
var split = dic[i].ToString().Split(',');
if (i == 4)
{
//跳过主键
continue;
}

if (dic.Count - 1 > i)
{
//非最后一个字段拼接sql加逗号
if (!string.IsNullOrWhiteSpace(split[1]))
{
sql  = split[0]   "=@"   split[0]   ",";
}

}

if (dic.Count - 1 == i)
{
var id = dic[4].ToString().Split(',');
if (!string.IsNullOrWhiteSpace(split[1]))
{
sql  = split[0]   "=@"   split[0];
}

sql  = " where "  id[0]   "=@"   id[0];
}
}
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 <= 0) { return null; }
int a = 0;
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[4].ToString().Split(',');

sql  = " IsDeleted='true'";
sql  = " where "   id[0]   "=@"   id[0];

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(0, sb.Length - 2)   " is null";
}
else if (sb.EndsWith("<>"))
{
sb = sb.Substring(0, sb.Length - 2)   " 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 == 1)
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 == 1)
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(0, tmpstr.Length - 1);
}
else if (exp is MethodCallExpression)
{
MethodCallExpression mce = (MethodCallExpression)exp;

string value = ExpressionRouter(mce.Arguments[0]).Replace("'", "");
string[] exps = mce.ToString().Split(new char[] { '.' });
string fieldName = exps[exps.Length-1].Split(new char[] { ')' })[0];

if (mce.Method.Name == "In")
return string.Format("{0} In ({1})", ExpressionRouter(mce.Arguments[0]), ExpressionRouter(mce.Arguments[1]));
else if (mce.Method.Name == "NotIn")
return string.Format("{0} Not In ({1})", ExpressionRouter(mce.Arguments[0]), ExpressionRouter(mce.Arguments[1]));
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 <= 0) { return null; }
int i = 0;
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 = -1;
            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 = -1;
            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 = -1;
            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 = -1;
            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 = -1;
            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 = -1;
            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.有空的各位就可以试试了

 

本文由wns9778.com发布于计算机教程,转载请注明出处:对Dapper的一点改造

关键词: wns9778.com

上一篇:【wns9778.com】JavaScript 那些不经意间发生的数据类

下一篇:没有了