【转载】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 - 1];
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#,感谢热心的园友。
转载自:http://www.cnblogs.com/landeanfen/p/4950336.html
【转载】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/ 多线程编程中的三个核心概念 原子性 这一点,跟数 ...
- Wireshark入门与进阶系列(二)
摘自http://blog.csdn.net/howeverpf/article/details/40743705 Wireshark入门与进阶系列(二) “君子生非异也,善假于物也”---荀子 本文 ...
- Bing Maps进阶系列二:使用GeocodeService进行地理位置检索
Bing Maps进阶系列二:使用GeocodeService进行地理位置检索 在<Bing Maps进阶系列一:初识Bing Maps地图服务>里已经对GeocodeService的功能 ...
- C#进阶系列——WebApi 路由机制剖析:你准备好了吗? 转载https://www.cnblogs.com/landeanfen/p/5501490.html
阅读目录 一.MVC和WebApi路由机制比较 1.MVC里面的路由 2.WebApi里面的路由 二.WebApi路由基础 1.默认路由 2.自定义路由 3.路由原理 三.WebApi路由过程 1.根 ...
- C#进阶系列——MEF实现设计上的“松耦合”(二)
前言:前篇 C#进阶系列——MEF实现设计上的“松耦合”(一) 介绍了下MEF的基础用法,让我们对MEF有了一个抽象的认识.当然MEF的用法可能不限于此,比如MEF的目录服务.目录筛选.重组部件等高级 ...
随机推荐
- C#--readlyonly关键字
字段可以使用readyonly修饰符声明.其作用类似声明一个字段为const,一旦值被设定就不能改变. const字段只能在字段的声明语句中初始化,而readyonly字段可以在下列任何位置设置它的值 ...
- PixelLink
简介 论文题目:PixelLink: Detecting Scene Text via Instance Segmentation 论文地址:https://arxiv.org/abs/1801.01 ...
- django 连接mysql 数据库
1.新建一个mysite项目:django-admin startproject mysite 2.进入项目目录,新建一个app : python manage.py startapp polls 3 ...
- ActiveMQ + NodeJS + Stomp 入门
NodeJS + stomp-client 入门 准备 下载ActiveMQ并安装 执行bin\win32\activemq.bat启动MQ服务 打开http://localhost:8161/adm ...
- unity 设置屏幕尺寸
在PlayerSettings中将web player的screen size设成600x900后,需要在Game视图下拉菜单中选Web(600x900),Game视图才能显示成我们设定的尺寸.
- Linux内存管理机制中buffer和cache的区别
Linux内存管理机制中buffer和cache的区别理解linux内存管理,需要深入了解linux内存的各个参数含义和规则,下面介绍一下Linux操作系统中内存buffer和cache的区别. Fr ...
- Common Probability Distributions
Common Probability Distributions Probability Distribution A probability distribution describes the p ...
- SD卡WAV音乐播放器(quartus11.0)(FAT32)(DE2-115)
准备工具:格式工厂,Windows录音机,SD卡(小于等于2G),音箱 首先,选一首MP3,用格式工场转化成WAV格式.可以看到转化后的文件变得很大,因为WAV就是AD采样值加个文件头,所以数据量巨大 ...
- Rewrite MSIL Code on the Fly with the .NET Framework Profiling API
http://clrprofiler.codeplex.com/ http://blogs.msdn.com/b/davbr/archive/2012/11/19/clrprofiler-4-5-re ...
- .net+jquery+ashx实现客户端模拟登陆扩展
客户端实现:login namespace LoginApp { partial class Form1 { /// <summary> /// 必需的设计器变量. /// </su ...