C#进阶系列——动态Lamada(二:优化)
前言:前几天写了一篇动态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(二:优化)的更多相关文章
- 【转载】C#进阶系列——动态Lamada(二:优化)
前言:前几天写了一篇动态Lamada的文章C#进阶系列——动态Lamada,受园友xiao99的启发,今天打算来重新优化下这个动态Lamada的工具类.在此做个笔记,以免以后忘了. 一.原理分析 上篇 ...
- C#进阶系列——动态Lamada
前言:在DDD系列文章里面,我们在后台仓储里面封装了传递Lamada表达式的通用方法,类似这样: public virtual IQueryable<TEntity> Find(Expre ...
- 【转载】C#进阶系列——动态Lamada
前言:在DDD系列文章里面,我们在后台仓储里面封装了传递Lamada表达式的通用方法,类似这样: public virtual IQueryable<TEntity> Find(Expre ...
- WCF 4.0 进阶系列 -- 随笔汇总
WCF4.0 进阶系列–前言 WCF4.0 进阶系列--第一章 WCF简介 WCF4.0进阶系列--第二章 寄宿WCF服务 WCF4.0进阶系列--第三章 构建健壮的程序和服务 WCF4.0进阶系列- ...
- 当我们说线程安全时,到底在说什么——Java进阶系列(二)
原创文章,同步发自作者个人博客,转载请以超链接形式在文章开头处注明出处http://www.jasongj.com/java/thread_safe/ 多线程编程中的三个核心概念 原子性 这一点,跟数 ...
- C#进阶系列——MEF实现设计上的“松耦合”(二)
前言:前篇 C#进阶系列——MEF实现设计上的“松耦合”(一) 介绍了下MEF的基础用法,让我们对MEF有了一个抽象的认识.当然MEF的用法可能不限于此,比如MEF的目录服务.目录筛选.重组部件等高级 ...
- C#进阶系列——DDD领域驱动设计初探(二):仓储Repository(上)
前言:上篇介绍了DDD设计Demo里面的聚合划分以及实体和聚合根的设计,这章继续来说说DDD里面最具争议的话题之一的仓储Repository,为什么Repository会有这么大的争议,博主认为主要原 ...
- Wireshark入门与进阶系列(二)
摘自http://blog.csdn.net/howeverpf/article/details/40743705 Wireshark入门与进阶系列(二) “君子生非异也,善假于物也”---荀子 本文 ...
- Bing Maps进阶系列二:使用GeocodeService进行地理位置检索
Bing Maps进阶系列二:使用GeocodeService进行地理位置检索 在<Bing Maps进阶系列一:初识Bing Maps地图服务>里已经对GeocodeService的功能 ...
随机推荐
- Pro HTML5 Programming(Second Edition)2.Canvas API(2)
1.在页面中加入canvas元素 eg: <!DOCTYPE html> <html lang="en"> <head> <meta ch ...
- jquery管理ajax异步-deferred对象
今天跟大家分享一个jquery中的对象-deferred.其实早在jquery1.5.0版本中就已经引入这个对象了.不过可能在实际开发过程中用到的并不多,所以没有太在意. 这里先不说deferred的 ...
- Objective-C 数据集合
1.NSSet 1.是一个无序的,管理多个对象的集合类,最大特点 是集合中不允许出现重复对象,和数学上的集合含义是一 样的 2.除了无序.不许重复之外,其它功能和NSArray是一样的 2.NSArr ...
- android TextView多行文本(超过3行)使用ellipsize="end"属性无效问题的解决方法
<TextView android:id="@+id/desc" android:layout_width="match_parent" android: ...
- Mac版PhpStorm之XAMPP整合apache服务器配置
版权声明:本文为博主原创文章,未经博主允许不得转载. 选择在PhpStorm集成apache服务器,下面是我自己的亲测的步骤. 1.如何修改apache默认端口 xampp apache默认的http ...
- 国外干货!6个方法助你设计出优秀的APP
伟大的设计来源于一致性和细致化,而其实只要有足够的纪律,每个团队都可以实现这一点. 品牌(源码:http://www.jinhusns.com/Products/Download/?type=xcj) ...
- C语言基于GTK+Libvlc实现的简易视频播放器(二)
简易视频播放器-全屏播放 一.课程说明 上一次我们使用gtk+libvlc实现了一个最简单的视频播放器,可以实现点击按钮暂定和停止播放视频,以及同步显 示视频播放进度,但即使作为一个视频播放器,只有这 ...
- PacificA中的租约与失效检测解读
PacificA是微软的在基于log的分布式存储系统中的复制技术. 由于配置管理器维护着当前配置的真实情况,因此主节点不必保持不变. 这是因为配置的本地视图在不同服务器上是不必同步的. 特别是,我们必 ...
- Linux 平台安装Oracle Database 12c
1)下载Oracle Database 12cRelease 1安装介质 官方的下载地址: 1:http://www.oracle.com/technetwork/database/enterpris ...
- ORACLE数据库的导入及导出
今天在客户这里导入oracle数据库,第一次导入oracle数据库,在这里记录一下,以后备用. 一.使用PLSQL导出导入ORACLE数据库: 1.打开plsql-->工具---->导出用 ...