C#进阶系列——动态Lamada(二:优化)

简介: 原文:C#进阶系列——动态Lamada(二:优化)前言:前几天写了一篇动态Lamada的文章C#进阶系列——动态Lamada,受园友xiao99的启发,今天打算来重新优化下这个动态Lamada的工具类。
原文: 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#,感谢热心的园友。

 

目录
相关文章
|
6天前
|
缓存 算法 测试技术
优化 C#编程性能的策略
【4月更文挑战第20天】优化C#性能策略包括:选择合适算法和数据结构,避免频繁对象创建,缓存常用数据,减少内存分配,使用异步编程,优化数据库操作(如合理查询和使用索引),利用多线程并行处理,精简代码,使用性能分析工具,硬件升级,以及进行性能测试。综合应用这些策略可提升程序性能和响应性。
|
设计模式 缓存 NoSQL
U3D客户端框架之类对象池技术优化C#语言GC
类对象池,类似对象池,顾名思义就是一定数量的已经创建好的类对象(Object)的集合。当需要创建对象时,先在池子中获取,如果池子中没有符合条件的对象,再进行创建新对象,同样,当对象需要销毁时,不做真正的销毁,而是将其对象SetActive(false),并存入池子中。这样就避免了大量对象的创建销毁,减少了GC,优化了性能。
|
算法 C# 决策智能
运筹优化学习16:【电招问题】Dial-a-Ride问题模型及C#实现的VNS程序
运筹优化学习16:【电招问题】Dial-a-Ride问题模型及C#实现的VNS程序
运筹优化学习16:【电招问题】Dial-a-Ride问题模型及C#实现的VNS程序
|
C# 决策智能
运筹优化学习13:C#中Gurobi的配置及测试
运筹优化学习13:C#中Gurobi的配置及测试
运筹优化学习13:C#中Gurobi的配置及测试
|
小程序 C# Python
【优化】C#小程序集成实现python定时段批量下载电子邮箱附件的bug排除
【优化】C#小程序集成实现python定时段批量下载电子邮箱附件的bug排除
97 0
|
1月前
|
C#
24. C# 编程:用户设定敌人初始血值的实现
24. C# 编程:用户设定敌人初始血值的实现
22 0
|
2月前
|
SQL 数据库连接 应用服务中间件
C#WinForm基础编程(三)
C#WinForm基础编程
78 0
|
2月前
C#WinForm基础编程(二)
C#WinForm基础编程
59 0
|
2月前
|
C# 数据安全/隐私保护
C#WinForm基础编程(一)
C#WinForm基础编程
62 0