Entity Framework若干个扩展
声明
这里有此东西是参考各大神修改和补充而来,有些地方就找不到原文章的地址了,一参考地址如下:
http://www.cnblogs.com/ahui/archive/2011/08/04/2127282.html
寄语
本着取之于大神,还之于大众的精神,我把本人整理以及扩展的一些重要部分贴出来,希望你也积极把你觉得好的扩展回应到此贴中。
1、ExecuteSqlCommand和SqlQuery扩展
作用:扩展后省去写大堆的new SqlParameter了
#region 动态执行Sql语句扩展
/// <summary>
/// 根据sql语句和参数的值动态生成Sqlparameter
/// </summary>
/// <param name="sql">sql语句</param>
/// <param name="values">值</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <returns></returns>
private static SqlParameter[] MakeSqlParameter(string sql, object[] values)
{
var matches = Regex.Matches(sql, @"@\w+");
List<string> paramNameList = new List<string>(); foreach (Match m in matches)
{
if (paramNameList.Contains(m.Value) == false)
{
paramNameList.Add(m.Value);
}
} if (values.Length != paramNameList.Count)
{
throw new ArgumentException("values的元素数目和Sql语句不匹配");
} int i = ;
var parameters = new SqlParameter[values.Length];
foreach (var pName in paramNameList)
{
parameters[i] = new SqlParameter(pName, values[i]);
i++;
}
return parameters;
} /// <summary>
/// 执行Sql命令
/// <example>ExecuteSqlCommandEx("delete from [Table] where ID=@0", Guid.Empty)</example>
/// </summary>
/// <param name="database">数据库</param>
/// <param name="sql">sql语句</param>
/// <param name="values">值</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <returns></returns>
public static int ExecuteSqlCommandEx(this Database database, string sql, params object[] values)
{
var param = DbSetExtended.MakeSqlParameter(sql, values);
return database.ExecuteSqlCommand(sql, param);
} /// <summary>
/// 执行Sql查询
/// <example>SqlQueryEx("select * from [Table] where name=@0 and password=@1", "abc", "123456")</example>
/// </summary>
/// <param name="database">数据库</param>
/// <param name="sql">sql语句</param>
/// <param name="values">值</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <returns></returns>
public static IEnumerable<TElement> SqlQueryEx<TElement>(this Database database, string sql, params object[] values)
{
var param = DbSetExtended.MakeSqlParameter(sql, values);
return database.SqlQuery<TElement>(sql, param);
}
#endregion
2、排序扩展
作用:支持用字符串直接描述排序,如:OrderBy("key1,key2,key3 desc,ke4"),方便和UI交互
#region 排序扩展
/// <summary>
/// 排序公共方法
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="source">数据源</param>
/// <param name="orderByKey">排序键排序键(不分大小写)</param>
/// <param name="orderByMethod">排序方法</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <returns></returns>
private static IOrderedQueryable<T> OrderByCommon<T>(IQueryable<T> source, string orderByKey, string orderByMethod) where T : class
{
if (string.IsNullOrEmpty(orderByKey))
{
throw new ArgumentNullException("orderByKey");
} Type sourceTtype = typeof(T);
PropertyInfo keyProperty = sourceTtype.GetProperties().FirstOrDefault(p => p.Name.ToLower().Equals(orderByKey.Trim().ToLower()));
if (keyProperty == null)
{
throw new ArgumentException("orderByKey不存在...");
} var param = Expression.Parameter(sourceTtype, "item");
var body = Expression.MakeMemberAccess(param, keyProperty);
var orderByLambda = Expression.Lambda(body, param); var resultExp = Expression.Call(typeof(Queryable), orderByMethod, new Type[] { sourceTtype, keyProperty.PropertyType }, source.Expression, Expression.Quote(orderByLambda));
var ordereQueryable = source.Provider.CreateQuery<T>(resultExp) as IOrderedQueryable<T>;
return ordereQueryable;
} /// <summary>
/// 排序
/// 选择升序或降序
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="source">数据源</param>
/// <param name="orderByKey">排序键排序键(不分大小写)</param>
/// <param name="ascending">是否升序</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <returns></returns>
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string orderByKey, bool ascending) where T : class
{
var methodName = ascending ? "OrderBy" : "OrderByDescending";
return DbSetExtended.OrderByCommon(source, orderByKey, methodName);
} /// <summary>
/// 排序次项
/// 选择升序或降序
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="source">数据源</param>
/// <param name="orderByKey">排序键(不分大小写)</param>
/// <param name="ascending">是否升序</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <returns></returns>
public static IOrderedQueryable<T> ThenBy<T>(this IOrderedQueryable<T> source, string orderByKey, bool ascending) where T : class
{
var methodName = ascending ? "ThenBy" : "ThenByDescending";
return DbSetExtended.OrderByCommon(source, orderByKey, methodName);
} /// <summary>
/// 多字段混合排序
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="source">数据源</param>
/// <param name="orderByString">排序字符串:例如CreateTime desc, ID asc 不区分大小写</param>
/// <exception cref="ArgumentNullException">orderByString</exception>
/// <returns></returns>
public static IOrderedQueryable<T> OrderBy<T>(this IQueryable<T> source, string orderByString) where T : class
{
Func<string[], bool> descFun = (item) => item.Length > && item[].Trim().ToLower().Equals("desc"); var parameters = orderByString
.Split(new string[] { "," }, StringSplitOptions.RemoveEmptyEntries)
.Select(item => item.Split(new string[] { " " }, StringSplitOptions.RemoveEmptyEntries))
.Select(item => new { Key = item.FirstOrDefault(), Asc = !descFun(item) })
.ToList(); if (parameters.Count == )
{
throw new ArgumentNullException("orderByString");
} var firstP = parameters.FirstOrDefault();
var orderQuery = source.OrderBy(firstP.Key, firstP.Asc);
parameters.Skip().ToList().ForEach(p => orderQuery = orderQuery.ThenBy(p.Key, p.Asc)); return orderQuery;
} /// <summary>
/// 排序
/// 选择升序或降序
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <typeparam name="TKey">排序键</typeparam>
/// <param name="source">数据源</param>
/// <param name="orderKeySelector">排序器</param>
/// <param name="ascending">是否升序</param>
/// <returns></returns>
public static IOrderedQueryable<T> OrderBy<T, TKey>(this IQueryable<T> source, Expression<Func<T, TKey>> orderKeySelector, bool ascending)
{
if (ascending)
{
return source.OrderBy(orderKeySelector);
}
else
{
return source.OrderByDescending(orderKeySelector);
}
} /// <summary>
/// 次项排序
/// 选择升序或降序
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <typeparam name="TKey">排序键</typeparam>
/// <param name="source">数据源</param>
/// <param name="orderKeySelector">排序器</param>
/// <param name="ascending">是否升序</param>
/// <returns></returns>
public static IOrderedQueryable<T> ThenBy<T, TKey>(this IOrderedQueryable<T> source, Expression<Func<T, TKey>> orderKeySelector, bool ascending)
{
if (ascending)
{
return source.ThenBy(orderKeySelector);
}
else
{
return source.ThenByDescending(orderKeySelector);
}
}
#endregion
3、单张表省略式Select的扩展
作用:扩展后省去写大堆的 item => new A(){A.key1 = item.key1....}
#region 查询方法的扩展
/// <summary>
/// Select方法的补充
/// rpy.SelectEx(item =>new TNew(){})等同rpy.Select(item => new TNew(){f1 = item.f1, f2 = item.f2 ,...})
/// rpy.SelectEx(item =>new TNew(){f1 = "something"})等同rpy.Select(item => new TNew(){ f1 ="something", f2 = item.f2 ,...})
/// 其它选择方法和原始Select方法一致
/// </summary>
/// <typeparam name="T">源实体类型</typeparam>
/// <typeparam name="TNew">新的实体类型</typeparam>
/// <param name="source">数据源</param>
/// <param name="selector">新对象实例</param>
/// <exception cref="ArgumentException"></exception>
/// <returns></returns>
public static IQueryable<TNew> SelectEx<T, TNew>(this IQueryable<T> source, Expression<Func<T, TNew>> selector) where T : class
{
if (selector == null)
{
throw new ArgumentNullException();
} var body = selector.Body as MemberInitExpression;
if (body != null)
{
var targetType = typeof(TNew);
var targetProperties = targetType.GetProperties().ToList();
var sourceProperties = typeof(T).GetProperties(); var parameter = selector.Parameters[];
var bindedMembers = body.Bindings.Select(b => b.Member).ToList();
var needBindProroties = targetProperties.Where(p => bindedMembers.Exists(m => m.Name.Equals(p.Name)) == false); var allBindings = body.Bindings.ToList();
foreach (var property in needBindProroties)
{
var sourceProperty = sourceProperties.FirstOrDefault(item => item.Name.Equals(property.Name));
if (sourceProperty != null)
{
var memberExp = Expression.MakeMemberAccess(parameter, sourceProperty);
var binding = Expression.Bind(property, memberExp);
allBindings.Add(binding);
}
} var targetNew = Expression.New(targetType);
var bodyNew = Expression.MemberInit(targetNew, allBindings);
selector = (Expression<Func<T, TNew>>)Expression.Lambda(bodyNew, parameter);
} return source.Select(selector);
}
#endregion
4、动态复杂的Where条件逻辑表达式生成的扩展
作用:生成复杂的过滤条件表达式,条件字段可以从UI上传过来再动态生成Func<T,boo>表达式
/// <summary>
/// Where条件扩展
/// 用于分步实现不确定条件个数的逻辑运算组织
/// <remarks>作者:陈国伟 日期:2013/05/07</remarks>
/// </summary>
public static class Where
{
/// <summary>
/// 逻辑枚举
/// </summary>
public enum LogicEnum
{
/// <summary>
/// 相等
/// </summary>
Equal,
/// <summary>
/// 不等
/// </summary>
NotEqual,
/// <summary>
/// 大于
/// </summary>
GreaterThan,
/// <summary>
/// 大于等于
/// </summary>
GreaterThanOrEqual,
/// <summary>
/// 小于
/// </summary>
LessThan,
/// <summary>
/// 小于等于
/// </summary>
LessThanOrEqual,
/// <summary>
/// 字条串的Contains
/// </summary>
Contains
} /// <summary>
/// 参数替换对象
/// </summary>
private class ParameterReplacer : ExpressionVisitor
{
/// <summary>
/// 表达式的参数
/// </summary>
public ParameterExpression ParameterExpression { get; private set; } /// <summary>
/// 参数替换对象
/// </summary>
/// <param name="paramExp">表达式的参数</param>
public ParameterReplacer(ParameterExpression paramExp)
{
this.ParameterExpression = paramExp;
} /// <summary>
/// 将表达式调度到此类中更专用的访问方法之一
/// </summary>
/// <param name="exp">表达式</param>
/// <returns></returns>
public Expression Replace(Expression exp)
{
return this.Visit(exp);
} /// <summary>
/// 获取表达式的参数
/// </summary>
/// <param name="p"></param>
/// <returns></returns>
protected override Expression VisitParameter(ParameterExpression p)
{
return this.ParameterExpression;
}
} /// <summary>
/// 返回默认为True的条件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static Expression<Func<T, bool>> True<T>()
{
return item => true;
} /// <summary>
/// 返回默认为False的条件
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static Expression<Func<T, bool>> False<T>()
{
return item => false;
} /// <summary>
/// 与逻辑运算
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="expLeft">表达式1</param>
/// <param name="expRight">表达式2</param>
/// <returns></returns>
public static Expression<Func<T, bool>> And<T>(this Expression<Func<T, bool>> expLeft, Expression<Func<T, bool>> expRight)
{
var candidateExpr = Expression.Parameter(typeof(T), "item");
var parameterReplacer = new ParameterReplacer(candidateExpr); var left = parameterReplacer.Replace(expLeft.Body);
var right = parameterReplacer.Replace(expRight.Body);
var body = Expression.And(left, right); return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
} /// <summary>
/// 或逻辑运算
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="expLeft">表达式1</param>
/// <param name="expRight">表达式2</param>
/// <returns></returns>
public static Expression<Func<T, bool>> Or<T>(this Expression<Func<T, bool>> expLeft, Expression<Func<T, bool>> expRight)
{
var candidateExpr = Expression.Parameter(typeof(T), "item");
var parameterReplacer = new ParameterReplacer(candidateExpr); var left = parameterReplacer.Replace(expLeft.Body);
var right = parameterReplacer.Replace(expRight.Body);
var body = Expression.Or(left, right); return Expression.Lambda<Func<T, bool>>(body, candidateExpr);
} /// <summary>
/// 动态生成Where逻辑表达式
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="member">实体的成员(不区分大小写)</param>
/// <param name="logic">逻辑关系</param>
/// <param name="matchValue">要匹配的值</param>
/// <exception cref="ArgumentNullException"></exception>
/// <exception cref="ArgumentException"></exception>
/// <returns></returns>
public static Expression<Func<T, bool>> Parse<T>(string member, LogicEnum logic, string matchValue)
{
if (string.IsNullOrEmpty(member))
{
throw new ArgumentNullException("member");
} var keyProperty = typeof(T).GetProperties().FirstOrDefault(item => item.Name.ToLower().Equals(member.Trim().ToLower()));
if (keyProperty == null)
{
throw new ArgumentException("member不存在");
} // item
var pExp = Expression.Parameter(typeof(T), "item");
// item.CreateTime
Expression memberExp = Expression.MakeMemberAccess(pExp, keyProperty); if (logic != LogicEnum.Contains)
{
// 是否是可空类型
bool memberIsNullableType = keyProperty.PropertyType.IsGenericType && keyProperty.PropertyType.GetGenericTypeDefinition().Equals(typeof(Nullable<>));
// 是可空类型则取类型的Value属性
if (memberIsNullableType == true)
{
// item.CreateTime.Value
memberExp = Expression.MakeMemberAccess(memberExp, keyProperty.PropertyType.GetProperty("Value"));
} // 目标值类型
Type valueType = keyProperty.PropertyType;
if (memberIsNullableType == true)
{
valueType = valueType.GetGenericArguments().FirstOrDefault();
} object value = matchValue;
if (valueType.Equals(typeof(string)) == false)
{
// value = DateTime.Parse(matchValue)
value = valueType.GetMethod("Parse", new Type[] { typeof(string) }).Invoke(null, new object[] { value });
} var valueExp = Expression.Constant(value, valueType);
// Expression.Equal
var expMethod = typeof(Expression).GetMethod(logic.ToString(), new Type[] { typeof(Expression), typeof(Expression) }); // item.CreateTime.Value == value
var body = expMethod.Invoke(null, new object[] { memberExp, valueExp }) as Expression;
return Expression.Lambda(body, pExp) as Expression<Func<T, bool>>;
}
else
{
// item.Member.Contains("something")
var body = Expression.Call(memberExp, typeof(string).GetMethod(logic.ToString()), Expression.Constant(matchValue, typeof(string)));
return Expression.Lambda(body, pExp) as Expression<Func<T, bool>>;
}
} /// <summary>
/// 动态生成和匹配参数数目相同的逻辑表达式并用Or关联起来
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="member">实体成员</param>
/// <param name="logic">逻辑关系</param>
/// <param name="matchValues">匹配值</param>
/// <returns></returns>
public static Expression<Func<T, bool>> ParseOr<T>(string member, LogicEnum logic, params string[] matchValues)
{
var where = Where.Parse<T>(member, logic, matchValues.FirstOrDefault());
matchValues.Skip().ToList().ForEach(value => where = where.Or(Where.Parse<T>(member, logic, value)));
return where;
} /// <summary>
/// 动态生成和成员目相同的逻辑表达式并用Or关联起来
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="members">实体成员</param>
/// <param name="logic">逻辑关系</param>
/// <param name="matchValue">匹配值</param>
/// <returns></returns>
public static Expression<Func<T, bool>> ParseOr<T>(string[] members, LogicEnum logic, string matchValue)
{
var where = Where.Parse<T>(members.FirstOrDefault(), logic, matchValue);
members.Skip().ToList().ForEach(member => where = where.Or(Where.Parse<T>(member, logic, matchValue)));
return where;
} /// <summary>
/// 动态生成和匹配参数数目相同的逻辑表达式并用And关联起来
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="member">实体成员</param>
/// <param name="logic">逻辑关系</param>
/// <param name="matchValues">匹配值</param>
/// <returns></returns>
public static Expression<Func<T, bool>> ParseAnd<T>(string member, LogicEnum logic, params string[] matchValues)
{
var where = Where.Parse<T>(member, logic, matchValues.FirstOrDefault());
matchValues.Skip().ToList().ForEach(value => where = where.And(Where.Parse<T>(member, logic, value)));
return where;
} /// <summary>
/// 动态生成和成员目相同的逻辑表达式并用And关联起来
/// </summary>
/// <typeparam name="T">实体类型</typeparam>
/// <param name="members">实体成员</param>
/// <param name="logic">逻辑关系</param>
/// <param name="matchValue">匹配值</param>
/// <returns></returns>
public static Expression<Func<T, bool>> ParseAnd<T>(string[] members, LogicEnum logic, string matchValue)
{
var where = Where.Parse<T>(members.FirstOrDefault(), logic, matchValue);
members.Skip().ToList().ForEach(member => where = where.And(Where.Parse<T>(member, logic, matchValue)));
return where;
}
}
Entity Framework若干个扩展的更多相关文章
- 采用EntityFramework.Extended 对EF进行扩展(Entity Framework 延伸系列2)
前言 Entity Framework 延伸系列目录 今天我们来讲讲EntityFramework.Extended 首先科普一下这个EntityFramework.Extended是什么,如下: 这 ...
- Entity Framework扩展库
这个Entity Framework扩展完全支持EF 5.0/6.0,项目地址 https://github.com/loresoft/EntityFramework.Extended,这个库支持批量 ...
- Entity Framework分页扩展
Entity Framework分页在我初入门时总是困扰这我,无论是SQL分页还是Entity Framework的分页,总是显得那么麻烦,因此对于Entity Framework单独封装了分页. 一 ...
- Entity Framework DbSet<T>之Include方法与IQueryable<T>扩展方法Include的使用
Entity Framework使用Code First方式时,实体之间已经配置好关系,根据实际情况某些情况下需要同时获取导航属性,比如获取商品的同时需要获取分类属性(导航属性),或者基于优化方面考虑 ...
- Entity Framework的扩展库
https://github.com/jcachat/EntityFramework.DynamicFilters Provides global & scoped filters for E ...
- Entity Framework 全面教程详解(转)
目录 预备知识 2 LINQ技术 2 LINQ技术的基础 - C#3.0 2 自动属性 2 隐式类型 2 对象初始化器与集合初始化器 3 匿名类 3 扩展方法 ...
- 转载Entity Framework全面教程
转载原地址:http://www.cnblogs.com/lsxqw2004/archive/2009/05/31/1495240.html#_Toc228672754 预备知识 2 LINQ技 ...
- Entity Framework 配置
Entity Framework的核心 – EDM(Entity Data Model) EDM概述 实体数据模型,简称EDM,由三个概念组成.概念模型由概念架构定义语言文件 (.csdl)来定义,映 ...
- Entity Framework 教程(转)
预备知识 2 LINQ技术 2 LINQ技术的基础 - C#3.0 2 自动属性 2 隐式类型 2 对象初始化器与集合初始化器 3 匿名类 3 扩展方法 ...
随机推荐
- 【nginx】负载均衡和proxy的配置
简介 使用upstream模块实现nginx负载均衡使用nginx_upstream_check_module模块实现后端服务器的健康检查使用nginx-sticky-module扩展模块实现Cook ...
- MyCat 学习笔记 第九篇.数据分片 之 数值分布
1 应用场景 Mycat 自带了多套数据分片的机制,其实根据数值分片也是比较简单,其实这个和数据取摸是类似的实现. 优.缺点同上一篇 2 环境说明 参考 <MyCat 学习笔记>第六篇. ...
- jQuery form插件的使用--ajaxForm()和ajaxSubmit()的可选参数项对象
一.前提说明 Form Plugin API 里提供了很多有用的方法可以让你轻松的处理表单里的数据和表单的提交过程. 测试环境:部署到Tomcat中的web项目. 二.简单介绍 本文演示的是:jQue ...
- JasperReports教程:Report Data Sources
原文地址:http://www.tutorialspoint.com/jasper_reports/jasper_report_data_sources.htm Datasources是一个结构化的数 ...
- UI设计实战篇——利用Bootstrap框架制作查询页面的界面
Bootstrap框架是一个前端UI设计的框架,它提供了统一的UI界面,简化了设计界面UI的过程(缺点是定制了界面,调整的余地不是太大).尤其是现在的响应时布局(我的理解是页面根据不同的分辨率,采用不 ...
- CSS3属性选择器与(:not)选择器
一:css3属性选择器: img[alt]{ border:2px dashed #000; } 这个选择器会匹配页面标签中任何一个含有alt属性的图片标签. 还可以通过设定属性值来缩小匹配范围: ...
- Apache轻量级性能测试工具
平时工作中会需要一些性能测试,简单的性能测试完全可以由AB来替代,而不需要动用LR这样重量级的工具. 此文简单介绍一下ab的工具使用与结果分析.当作个笔记,以便以后查阅. 1.安装:要使用AB,需要先 ...
- java 21 - 13 IO流之序列化和反序列化
序列化流:把对象按照流一样的方式存入文本文件或者在网络中传输.对象 -- 流数据(ObjectOutputStream) 构造方法:ObjectInputStream(InputStream in) ...
- Sublime Text2 新建文件快速生成Html头部信息和炫酷的代码补全
预备:安装emmet插件(previously known as Zen Coding) 方法一 package control法: 上一篇博客已经介绍了如何安装package control.打开 ...
- 优化mysql主从下的slave延迟问题
一般而言,slave相对master延迟较大,其根本原因就是slave上的复制线程没办法真正做到并发.简单说,在master上是并发模式(以InnoDB引擎为主)完成事务提交的,而在slave上,复制 ...