• c# 用Expression表达式 解决类似于sql中 select 中 in 的查询


    由于项目中需要,需要实现类似于sql语句中select里面in的查询语法,

    所以上网搜查了下资料,由于时间关系,以下资料简略,后续再补充。。。

    需要实现,下面的效果

    sql:... where Id in (4,6,....)

    someList.where(c=> c.Id==4 || c.Id==6 || ...)

            public static Expression<Func<T, bool>> GetConditionExpression<T>(int[] options, string proName)
            {
                //1)声明一个变量c
                ParameterExpression left = Expression.Parameter(typeof(T), "c");//c=>
                Expression expression = Expression.Constant(false);
    
                //常量值数组:options
                foreach (var optionId in options)
                {
                    //2)c.属性 调用c.的属性--T的属性proName,先获取属性
                    //a、 获取属性--通过反射
                    PropertyInfo proInfo = typeof(T).GetProperty(proName);
                    //b、 c.fieldName  通过left来调用
                    MemberExpression memberExpression = Expression.Property(left, proInfo);
    
                    //3)== Equeals是个方法,是属性proName的方法
                    //a、 常量optionId
                    ConstantExpression constant = Expression.Constant(optionId, typeof(int));
                    //b、 c.proName==常量optionId
                    Expression right = Expression.Equal(memberExpression, constant);
    
                    expression = Expression.Or(right, expression);
                    //c.Id==optionId || c.Id==optionId ||... 
    
                }
                Expression<Func<T, bool>> finalExpression
                    = Expression.Lambda<Func<T, bool>>(expression, new ParameterExpression[] { left });
                return finalExpression;
            }

    运行截图:

     

    最后拼接的效果

     

    参考的资料:

    看到此图后大家肯定会说,这很简单嘛

    将所有的选项 拼成“'1-3','5-9'”  然后放到 in 的字句后面,一查就出来了。

    这样做的确在逻辑上没有问题,可是大家有没有想过这个问题,过度的和业务耦合虽然能够解决

    现在的需求但是却牺牲了代码优雅和可维护性

     

    查询的目的要实现这样的效果 ,

     someList.where(c=>c.Name.contains("someName")||c.Name.Contains("someName")||...)

     public static Expression<Func<T, bool>> GetConditionExpression<T>(string[] options, string fieldName)
            {
                ParameterExpression left = Expression.Parameter(typeof(T), "c");//c=>
                Expression expression = Expression.Constant(false);
                foreach (var optionName in options)
                {
                    Expression right = Expression.Call
                           (
                              Expression.Property(left, typeof(T).GetProperty(fieldName)),  //c.DataSourceName
                              typeof(string).GetMethod("Contains", new Type[] { typeof(string) }),// 反射使用.Contains()方法                         
                             s Expression.Constant(optionName)           // .Contains(optionName)
                           );
                    expression = Expression.Or(right, expression);//c.DataSourceName.contain("") || c.DataSourceName.contain("") 
                }
                Expression<Func<T, bool>> finalExpression
                    = Expression.Lambda<Func<T, bool>>(expression, new ParameterExpression[] { left });
                return finalExpression;
            }

     

    本文引自:

    https://www.cnblogs.com/JimmyZheng/archive/2012/02/23/2364154.html

    https://blog.csdn.net/liyou123456789/article/details/119967779

  • 相关阅读:
    在Intellij idea 2017中运行tomcat 8.5
    Servlet技术之服务器的安装和配置
    Servlet&&Jsp 概述
    linux 下 tomcat 安装
    执行数据库的更新操作
    JDBC
    Mysql 命令
    hdoj2036 改革春风吹满地——叉积
    常规设置
    pytorch本地安装
  • 原文地址:https://www.cnblogs.com/ggll611928/p/16206692.html
Copyright © 2020-2023  润新知