前言:前几天写了一篇动态Lamada的文章C#进阶系列——动态Lamada,受园友xiao99的启发,今天打算来重新优化下这个动态Lamada的工具类。在此做个笔记,以免以后忘了。

一、原理分析

上篇里面我们说了动态Lamada的使用必要性以及使用场景,但是感觉用在项目里面还不太方便,最难用的就是需要传递属性名称的字符串,感觉这有点太lower了。然后就是那个枚举的使用着实感觉没啥必要,我们只需要将Contains、Equal、LessThan、GreaterThan等方法分别封装一个独立的方法即可。好了,多说容易让人头晕,直接上代码吧。

二、代码示例

  public class LamadaExtention<Dto> where Dto:new ()
{
private List<Expression> m_lstExpression = null;
private ParameterExpression m_Parameter = null; public LamadaExtention()
{
m_lstExpression = new List<Expression>();
m_Parameter = Expression.Parameter(typeof(Dto), "x");
}

     //只读属性,返回生成的Lamada
public Expression<Func<Dto, bool>> Lamada
{
        
get
{
return GetLambda();
}
} /// <summary>
/// 字符串Contains筛选
/// </summary>
/// <param name="expProperty"></param>
/// <param name="strValue"></param>
public void Contains(Expression<Func<Dto, string>> expProperty, object strValue)
{
Expression expRes = Expression.Call(expProperty.Body, typeof(string).GetMethod("Contains"),
Expression.Constant(strValue));
m_lstExpression.Add(expRes);
} /// <summary>
/// 等于
/// </summary>
/// <param name="expProperty"></param>
/// <param name="strValue"></param>
public void Equal(Expression<Func<Dto, object>> expProperty, object strValue)
{
var member = GetMemberExpression(expProperty);
Expression expRes = Expression.Equal(member, Expression.Constant(strValue, member.Type));
m_lstExpression.Add(expRes);
} /// <summary>
/// 小于
/// </summary>
/// <param name="expProperty"></param>
/// <param name="strValue"></param>
public void LessThan(Expression<Func<Dto, object>> expProperty, object strValue)
{
var member = GetMemberExpression(expProperty);
Expression expRes = Expression.LessThan(member, Expression.Constant( strValue, member.Type));
m_lstExpression.Add(expRes);
} /// <summary>
/// 小于等于
/// </summary>
/// <param name="expProperty"></param>
/// <param name="strValue"></param>
public void LessThanOrEqual(Expression<Func<Dto, object>> expProperty, object strValue)
{
var member = GetMemberExpression(expProperty);
Expression expRes = Expression.LessThanOrEqual(member, Expression.Constant(strValue, member.Type));
m_lstExpression.Add(expRes);
} /// <summary>
/// 大于
/// </summary>
/// <param name="expProperty"></param>
/// <param name="strValue"></param>
public void GreaterThan(Expression<Func<Dto, object>> expProperty, object strValue)
{
var member = GetMemberExpression(expProperty);
Expression expRes = Expression.GreaterThan(member, Expression.Constant(strValue, member.Type));
m_lstExpression.Add(expRes);
} /// <summary>
/// 大于等于
/// </summary>
/// <param name="expProperty"></param>
/// <param name="strValue"></param>
public void GreaterThanOrEqual(Expression<Func<Dto, object>> expProperty, object strValue)
{
var member = GetMemberExpression(expProperty);
Expression expRes = Expression.GreaterThanOrEqual(member, Expression.Constant(strValue, member.Type));
m_lstExpression.Add(expRes);
}private Expression<Func<Dto, bool>> GetLambda()
{
Expression whereExpr = null;
foreach (var expr in this.m_lstExpression)
{
if (whereExpr == null) whereExpr = expr;
else whereExpr = Expression.And(whereExpr, expr);
}
if (whereExpr == null)
return null;
return Expression.Lambda<Func<Dto, Boolean>>(whereExpr, m_Parameter);
} //得到MemberExpression
private MemberExpression GetMemberExpression(Expression<Func<Dto, object>> exp)
{
var arrSplit = exp.Body.ToString().Split("(.)".ToCharArray(), StringSplitOptions.RemoveEmptyEntries);
var strProperty = arrSplit[arrSplit.Length - ];
MemberExpression member = Expression.PropertyOrField(m_Parameter, strProperty);
return member;
}
}

可以看出,对于常用的操作我们封装了Contains、Equal、LessThan、LessThanOrEqual、GreaterThan、GreaterThanOrEqual六个方法,除了Contains方法的参数直接使用了Expression<Func<DTO, string>>类型以为,其他都用的Expression<Func<DTO, object>>。因为Contains方法只可能是string类型的变量操作,而其他操作可能涉及其他类型,就是为了传这个object类型,有个问题博主调试了很久,由于传过来的是object,这个要得到属性的真是类型貌似不那么容易了,找了很久都没找到。最后只能通过GetMemberExpression这个方法来得到MemberExpression。

还是来看看如何使用:

     public object GetUsers(int limit, int offset, string username, string fullname)
{
var oLamadaExtention = new LamadaExtention<DTO_TR_SYS_USERS>();
oLamadaExtention.Equal(x => x.USER_NAME, username);
oLamadaExtention.LessThan(x => x.MODIFYTIME, DateTime.Now);
       var lstRes = UserManager.Find(oLamadaExtention.lamada).ToList();
     }

最大的方便就是我们想要筛选的字段可以通过lamada点出来了,再看看之前的那种用法

oLamadaExtention.GetExpression("USER_NAME", username, ExpressionType.Contains);

有没有瞬间高大上。USER_NAME直接点出来,比敲字符串要爽吧。感谢神奇的Lamada,感谢全能的C#,感谢热心的园友。

C#进阶系列——动态Lamada(二:优化)的更多相关文章

  1. 【转载】C#进阶系列——动态Lamada(二:优化)

    前言:前几天写了一篇动态Lamada的文章C#进阶系列——动态Lamada,受园友xiao99的启发,今天打算来重新优化下这个动态Lamada的工具类.在此做个笔记,以免以后忘了. 一.原理分析 上篇 ...

  2. C#进阶系列——动态Lamada

    前言:在DDD系列文章里面,我们在后台仓储里面封装了传递Lamada表达式的通用方法,类似这样: public virtual IQueryable<TEntity> Find(Expre ...

  3. 【转载】C#进阶系列——动态Lamada

    前言:在DDD系列文章里面,我们在后台仓储里面封装了传递Lamada表达式的通用方法,类似这样: public virtual IQueryable<TEntity> Find(Expre ...

  4. WCF 4.0 进阶系列 -- 随笔汇总

    WCF4.0 进阶系列–前言 WCF4.0 进阶系列--第一章 WCF简介 WCF4.0进阶系列--第二章 寄宿WCF服务 WCF4.0进阶系列--第三章 构建健壮的程序和服务 WCF4.0进阶系列- ...

  5. 当我们说线程安全时,到底在说什么——Java进阶系列(二)

    原创文章,同步发自作者个人博客,转载请以超链接形式在文章开头处注明出处http://www.jasongj.com/java/thread_safe/ 多线程编程中的三个核心概念 原子性 这一点,跟数 ...

  6. C#进阶系列——MEF实现设计上的“松耦合”(二)

    前言:前篇 C#进阶系列——MEF实现设计上的“松耦合”(一) 介绍了下MEF的基础用法,让我们对MEF有了一个抽象的认识.当然MEF的用法可能不限于此,比如MEF的目录服务.目录筛选.重组部件等高级 ...

  7. C#进阶系列——DDD领域驱动设计初探(二):仓储Repository(上)

    前言:上篇介绍了DDD设计Demo里面的聚合划分以及实体和聚合根的设计,这章继续来说说DDD里面最具争议的话题之一的仓储Repository,为什么Repository会有这么大的争议,博主认为主要原 ...

  8. Wireshark入门与进阶系列(二)

    摘自http://blog.csdn.net/howeverpf/article/details/40743705 Wireshark入门与进阶系列(二) “君子生非异也,善假于物也”---荀子 本文 ...

  9. Bing Maps进阶系列二:使用GeocodeService进行地理位置检索

    Bing Maps进阶系列二:使用GeocodeService进行地理位置检索 在<Bing Maps进阶系列一:初识Bing Maps地图服务>里已经对GeocodeService的功能 ...

随机推荐

  1. javascript中concat方法深入理解

    最近在恶补js知识的时候,总是会因为js强大的语法而感到震撼.因为以前对前端方面的疏忽,导致了一些理解的错误.因此痛改前非,下定决心,不管做什么事情,都要有专研的精神. 在介绍前,抛出一个问题:如何将 ...

  2. Oracle常用SQL查询(2)

    三.查看数据库的SQL 1 .查看表空间的名称及大小 select  t.tablespace_name,  round ( sum (bytes / ( 1024 * 1024 )), 0 ) ts ...

  3. JSPatch使用小记

    hotfix的作用众所周知,Android和iOS都有各自的技术,但是相比Android的当天发布来说(如果你们的项目不需要灰度),iOS热更新的意义更加重大.因为iOS审核周期长不说,而且运气不好会 ...

  4. Gui系统之View体系(2)---View的setContent

    1.从SetContentView讲起 1.1Activty的setContentView里面的内容 public void setContentView(@LayoutRes int layoutR ...

  5. JVM-内存管理

    都说搞C的牛叉,那是因为C解决问题,全靠程序员自己,他们对自己的程序在内存中是什么样了如指掌.而Java呢不需要有太多操作系统的知识,不用时刻注意内存的问题,但这不代表我们就不用去了解它背后的原理.J ...

  6. SqlServer数据类型

    Character 字符串: 数据类型 描述 存储 char(n) 固定长度的字符串.最多 8,000 个字符. n varchar(n) 可变长度的字符串.最多 8,000 个字符.   varch ...

  7. SQL Server 复制快照执行错误 错误代码 14068

    问题描述: 使用基于快照初始化的事务复制,在上次发布的时候,添加项,执行快照agent,报错,错误信息: Error messages:Message: The subscription status ...

  8. C++ 栈和堆的区别

    C++中的存储区分为全局数据区.代码区.堆.栈. 全局数据区存放静态数据.全局变量.常量. 代码区存放所有类成员函数和非成员函数的代码. 栈区存放用于函数的返回地址.形参.局部变量.返回类型. 堆区存 ...

  9. PHP函数整理(一)

    以下均参考自 php.net 及 W3School 1. urlencode() : 此函数便于将字符串编码并将其用于URL的请求部分,同时它还便于将变量传递给下一页. 函数语法 : string u ...

  10. Zabbix监控VMare Vcenter

    1.参照Zabbix文档配置 依照官方文档配置,没什么说的. zabbix官方文档:https://www.zabbix.com/documentation/3.2/manual/vm_monitor ...