C# linq where 条件表达式动态生成

文章介绍了C#中的ConditionExpression类,用于构建复杂的逻辑表达式,包括运算符重载和转换,以及如何将其与LINQ查询的WhereExpression方法结合,以实现动态查询条件的设置。
摘要由CSDN通过智能技术生成

基础类 

public class ConditionExpression
{
    public ConditionExpression()
    {

    }
    public ConditionExpression(ConditionExpression left, ConditionExpression right, string op)
    {
        this.Left = left;
        this.Right = right;
        this.Op = op;
    }

    private ConditionExpression _left;
    public ConditionExpression Left
    {
        get
        {
            return _left;
        }
        set
        {
            if (value.isbottom)
            {
                value.isfield = true;
            }
            _left = value;
        }
    }
    public ConditionExpression Right { get; set; }
    public string Op { get; set; }
    private bool isfield = false;
    private bool isbottom = false;
    private object _value;
    public object Value
    {
        get { return _value; }
        set { _value = value; }
    }

    public override string ToString()
    {
        if (isbottom)
        {
            if (!isfield)
            {
                if (Value == null)
                    return null;
                return  Convert.ToString("'" + Value + "'");
            }
            else
            {
                return Convert.ToString(Value);
            }
        }

        else
        {
            if(Right==null&& Op=="=")
                return Left + " is null ";
            else 
            return Left + " " + Op + " " + Right;
        }

    }

    public static implicit operator ConditionExpression(string value)
    {
        ConditionExpression condition = new ConditionExpression();
        condition.Value = value;
        condition.isbottom = true;
        return condition;
    }

    public static implicit operator ConditionExpression(int value)
    {
        ConditionExpression condition = new ConditionExpression();
        condition.Value = value;
        condition.isbottom = true;
        return condition;
    }
    public static ConditionExpression operator &(ConditionExpression Condition1, ConditionExpression Condition2)
    {
        if (Condition1 != null && Condition2 != null)
        {
            ConditionExpression condition = new ConditionExpression();
            condition.Left = Condition1;
            condition.Right = Condition2;
            condition.Op = "and";
            return condition;
        }
        else if (Condition1 != null)
        {
            return Condition1;
        }
        else if (Condition2 != null)
        {
            return Condition2;
        }
        return null;
    }

    public static ConditionExpression operator |(ConditionExpression Condition1, ConditionExpression Condition2)
    {
        if (Condition1 != null && Condition2 != null)
        {
            ConditionExpression condition = new ConditionExpression();
            condition.Left = Condition1;
            condition.Right = Condition2;
            condition.Op = "or";
            return condition;
        }
        else if (Condition1 != null)
        {
            return Condition1;
        }
        else if (Condition2 != null)
        {
            return Condition2;
        }
        return null;
    }
    private bool IsCompareThan<T>(Type PropertyType)
    {
        if (PropertyType.Name == typeof(Int32).Name || PropertyType.Name == typeof(Int64).Name ||
            PropertyType.Name == typeof(Int16).Name || PropertyType.Name == typeof(float).Name ||
            PropertyType.Name == typeof(decimal).Name || PropertyType.Name == typeof(double).Name ||
             PropertyType.Name == typeof(DateTime).Name)
        {
            return true;
        }
        else return false;
    }

    private ParameterExpression parameterExpression { get; set; }
    private Expression GetBodyExpression<T>(ConditionExpression parent)
    {
        if (isfield && isbottom)
        {
            Type PropertyType = typeof(T).GetProperty(parent.Left.ToString()).PropertyType;
            if (PropertyType.IsGenericType && PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                PropertyType = PropertyType.GetGenericArguments()[0];
            }
            Expression ru;
            MemberExpression memberExpression = Expression.Property(parent.parameterExpression, Convert.ToString(Value));
            if (IsCompareThan<T>(PropertyType))
            {
                ru = memberExpression;
            }
            else
            {
                if (parent.Op == "=")
                {
                    ru = memberExpression;
                }
                else if (parent.Op == ">" || parent.Op == ">=" || parent.Op == "<" || parent.Op == "<=")
                {
                    MethodInfo method = memberExpression.Type.GetMethod("CompareTo", new Type[] { typeof(string) });
                    Object Ovalue = Convert.ChangeType(parent.Right.Value, PropertyType);
                    ConstantExpression rightExpression = Expression.Constant(Ovalue, PropertyType);
                    MethodCallExpression methodCallExpression = Expression.Call(memberExpression, method, rightExpression);
                    ru = methodCallExpression;
                }
                else if (parent.Op == "like")
                {
                    MethodInfo method = memberExpression.Type.GetMethod("Contains", new Type[] { typeof(string) });
                    Object Ovalue = Convert.ChangeType(parent.Right.Value, PropertyType);
                    ConstantExpression rightExpression = Expression.Constant(Ovalue, PropertyType);
                    MethodCallExpression methodCallExpression = Expression.Call(memberExpression, method, rightExpression);
                    ru = methodCallExpression;
                }
                else
                {
                    throw new Exception("不支持的比较操作符与数据类型 参考 >=<like");
                }
            }

            return ru;
        }
        else if (isbottom)
        {
            Type PropertyType = typeof(T).GetProperty(parent.Left.ToString()).PropertyType;
            Type BPropertyType = PropertyType;
            ConstantExpression constantExpression = null;
            if (PropertyType.IsGenericType && PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                PropertyType = PropertyType.GetGenericArguments()[0];
            }

            Object Ovalue = Convert.ChangeType(Value, PropertyType);

            if (IsCompareThan<T>(PropertyType))
            {
                constantExpression = Expression.Constant(Ovalue, PropertyType);
            }
            else
            {
                if (parent.Op == "=")
                {
                    if (PropertyType.Name == typeof(bool).Name)
                    {
                        constantExpression = Expression.Constant(Ovalue, typeof(bool));
                    }
                    else
                    {
                        constantExpression = Expression.Constant(Value, typeof(string));
                    }

                }
                else if (parent.Op == "like")
                {
                    constantExpression = Expression.Constant(true, typeof(bool));
                }
                else if (parent.Op == ">" || parent.Op == ">=" || parent.Op == "<" || parent.Op == "<=")
                {
                    constantExpression = Expression.Constant(0, typeof(int));
                }
                else
                {
                    throw new Exception("不支持的比较操作符与数据类型 参考 >=<like");
                }
            }
            Expression typeFilter = constantExpression;
            if (BPropertyType.IsGenericType && BPropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
            {
                typeFilter = Expression.Convert(constantExpression, BPropertyType);
            }
          ;
            return typeFilter;

        }

        if (Op == ">")
        {
            parameterExpression = parent.parameterExpression;
            Expression body = Expression.GreaterThan(Left.GetBodyExpression<T>(this), Right.GetBodyExpression<T>(this));
            return body;
        }
        if (Op == ">=")
        {
            parameterExpression = parent.parameterExpression;
            Expression body = Expression.GreaterThanOrEqual(Left.GetBodyExpression<T>(this), Right.GetBodyExpression<T>(this));
            return body;
        }
        if (Op == "<")
        {
            parameterExpression = parent.parameterExpression;
            Expression body = Expression.LessThan(Left.GetBodyExpression<T>(this), Right.GetBodyExpression<T>(this));
            return body;
        }
        if (Op == "<=")
        {
            parameterExpression = parent.parameterExpression;
            Expression body = Expression.LessThanOrEqual(Left.GetBodyExpression<T>(this), Right.GetBodyExpression<T>(this));
            return body;
        }

        if (Op == "=")
        {
            parameterExpression = parent.parameterExpression;

            Expression body = Expression.Equal(Left.GetBodyExpression<T>(this), Right.GetBodyExpression<T>(this));
            return body;
        }

        if (Op == "like")
        {
            parameterExpression = parent.parameterExpression;
            Expression body = Expression.Equal(Left.GetBodyExpression<T>(this), Right.GetBodyExpression<T>(this));
            return body;
        }

        if (Op == "and")
        {
            parameterExpression = parent.parameterExpression;
            Expression body = Expression.And(Left.GetBodyExpression<T>(this), Right.GetBodyExpression<T>(this));
            return body;
        }

        if (Op == "or")
        {
            parameterExpression = parent.parameterExpression;
            Expression body = Expression.Or(Left.GetBodyExpression<T>(this), Right.GetBodyExpression<T>(this));
            return body;
        }
        throw new NotImplementedException();
    }



    public Expression ToExpression<T>(ParameterExpression parameter = null)
    {
        parameterExpression = Expression.Parameter(typeof(T), "o");
        Expression body = GetBodyExpression<T>(this);
        Expression expression = Expression.Lambda(body, parameterExpression);
        return expression;
    }
}
 public static  class Extensions
 {
     public static Expression<Func<T, bool>> ToWhereExpression<T>(this Condition condition,bool ignoreTypeError=true )
     {
        
         ConditionExpression andCondition = null;
         ConditionExpression expression = null;
         if (condition != null)
         {
             if (condition.AndCondition.Count > 0)
             {
                 
                 for (int i = 0; i < condition.AndCondition.Count; i++)
                 {

                     if (!string.IsNullOrEmpty(condition.AndCondition[i].Value))
                     {
                         
                         ConditionExpression cexpre = new ConditionExpression();
                         string Field=   condition.AndCondition[i].Field;
                         string Value = condition.AndCondition[i].Value;
                      
                         if (ignoreTypeError)
                         {
                             Type PropertyType = typeof(T).GetProperty(Field).PropertyType;
                             if (PropertyType.IsGenericType && PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                             {
                                 PropertyType = PropertyType.GetGenericArguments()[0];
                             }
                             try
                             {
                                 if (PropertyType == typeof(bool)&&Value=="1")
                                 {
                                     Value = "true";
                                 }
                                 if (PropertyType == typeof(bool) && Value == "0")
                                 {
                                     Value = "false";
                                 }
                                 Object Ovalue = Convert.ChangeType(Value, PropertyType);
                                 cexpre.Left = Field;
                                 cexpre.Right = Value;
                                 cexpre.Op = condition.AndCondition[i].Op;
                             }
                             catch 
                             {
                                 cexpre = null;
                             }
                         }
                         else
                         {
                             cexpre.Left = Field;
                             cexpre.Right = Value;
                             cexpre.Op = condition.AndCondition[i].Op;
                         }

                         andCondition = andCondition & cexpre;

                     }

                 }
             }
             ConditionExpression orCondition = null;
             if (condition.OrCondition.Count > 0)
             {
                 for (int i = 0; i < condition.OrCondition.Count; i++)
                 {
                     if (!string.IsNullOrEmpty(condition.OrCondition[i].Value))
                     {
                         ConditionExpression cexpre = new ConditionExpression();


                         string Field = condition.OrCondition[i].Field;
                         string Value = condition.OrCondition[i].Value;

                         if (ignoreTypeError)
                         {
                             Type PropertyType = typeof(T).GetProperty(Field).PropertyType;
                             if (PropertyType.IsGenericType && PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                             {
                                 PropertyType = PropertyType.GetGenericArguments()[0];
                             }
                             try
                             {
                                 Object Ovalue = Convert.ChangeType(Value, PropertyType);
                                 cexpre.Left = Field;
                                 cexpre.Right = Value;
                                 cexpre.Op = condition.OrCondition[i].Op;
                             }
                             catch
                             {
                                 cexpre = null;
                             }
                         }
                         else
                         {
                             cexpre.Left = Field;
                             cexpre.Right = Value;
                             cexpre.Op = condition.OrCondition[i].Op;
                         }

                        
                         orCondition = orCondition | cexpre;
                     }
                 }
             }

             if (condition.Concat == "and")
             {
                 expression = andCondition & orCondition;
             }
             if (condition.Concat == "or")
             {
                 expression = andCondition | orCondition;
             }
         }
       
         if (condition == null|| expression==null)
         {
             var be = Expression.Equal(Expression.Constant(1), Expression.Constant(1));
             var ree = Expression.Lambda(be, Expression.Parameter(typeof(T), "o"));
             return (Expression<Func<T, bool>>)ree;
         }
         LambdaExpression re = (LambdaExpression ) expression.ToExpression<T>();
         return (Expression<Func<T, bool>>)re;
     }
     public static Expression<Func<T, bool>> ToWhereExpression<T>(this IQueryable<T> iqueryable, Condition condition, bool ignoreTypeError = true)
     {

         ConditionExpression andCondition = null;
         ConditionExpression expression = null;
         if (condition != null)
         {
             if (condition.AndCondition.Count > 0)
             {

                 for (int i = 0; i < condition.AndCondition.Count; i++)
                 {

                     if (!string.IsNullOrEmpty(condition.AndCondition[i].Value))
                     {

                         ConditionExpression cexpre = new ConditionExpression();
                         string Field = condition.AndCondition[i].Field;
                         string Value = condition.AndCondition[i].Value;

                         if (ignoreTypeError)
                         {
                             Type PropertyType = typeof(T).GetProperty(Field).PropertyType;
                             if (PropertyType.IsGenericType && PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                             {
                                 PropertyType = PropertyType.GetGenericArguments()[0];
                             }
                             try
                             {
                                 if (PropertyType == typeof(bool) && Value == "1")
                                 {
                                     Value = "true";
                                 }
                                 if (PropertyType == typeof(bool) && Value == "0")
                                 {
                                     Value = "false";
                                 }
                                 Object Ovalue = Convert.ChangeType(Value, PropertyType);
                                 cexpre.Left = Field;
                                 cexpre.Right = Value;
                                 cexpre.Op = condition.AndCondition[i].Op;
                             }
                             catch
                             {
                                 cexpre = null;
                             }
                         }
                         else
                         {
                             cexpre.Left = Field;
                             cexpre.Right = Value;
                             cexpre.Op = condition.AndCondition[i].Op;
                         }

                         andCondition = andCondition & cexpre;

                     }

                 }
             }
             ConditionExpression orCondition = null;
             if (condition.OrCondition.Count > 0)
             {
                 for (int i = 0; i < condition.OrCondition.Count; i++)
                 {
                     if (!string.IsNullOrEmpty(condition.OrCondition[i].Value))
                     {
                         ConditionExpression cexpre = new ConditionExpression();


                         string Field = condition.OrCondition[i].Field;
                         string Value = condition.OrCondition[i].Value;

                         if (ignoreTypeError)
                         {
                             Type PropertyType = typeof(T).GetProperty(Field).PropertyType;
                             if (PropertyType.IsGenericType && PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>))
                             {
                                 PropertyType = PropertyType.GetGenericArguments()[0];
                             }
                             try
                             {
                                 Object Ovalue = Convert.ChangeType(Value, PropertyType);
                                 cexpre.Left = Field;
                                 cexpre.Right = Value;
                                 cexpre.Op = condition.OrCondition[i].Op;
                             }
                             catch
                             {
                                 cexpre = null;
                             }
                         }
                         else
                         {
                             cexpre.Left = Field;
                             cexpre.Right = Value;
                             cexpre.Op = condition.OrCondition[i].Op;
                         }


                         orCondition = orCondition | cexpre;
                     }
                 }
             }

             if (condition.Concat == "and")
             {
                 expression = andCondition & orCondition;
             }
             if (condition.Concat == "or")
             {
                 expression = andCondition | orCondition;
             }
         }

         if (condition == null || expression == null)
         {
             var be = Expression.Equal(Expression.Constant(1), Expression.Constant(1));
             var ree = Expression.Lambda(be, Expression.Parameter(typeof(T), "o"));
             return (Expression<Func<T, bool>>)ree;
         }
         LambdaExpression re = (LambdaExpression)expression.ToExpression<T>();
         return (Expression<Func<T, bool>>)re;
     }


 }
public class Condition
{
    public Condition()
    {
        AndCondition = new List<ConditionModel>();
        OrCondition = new List<ConditionModel>();
        Concat = "and";
    }
    public  List<ConditionModel> AndCondition { get; set; }
    public List<ConditionModel> OrCondition { get; set; }
    public string Concat { get; set; }
}
public class ConditionModel
{
    public string Field { get; set; }
    public string Value { get; set; }
    public string Op { get; set; }
}

使用方法

var condition= new Condition ()
//第一种  匿名

var query = from a in  xxx
             select new
             {
                //
             };
query= query.Where(query.ToWhereExpression(condition));

//第二种

condition.OrCondition.Add(
new ConditionModel() { Field = "xxx", Value = 'xxx_SearchValue', Op = "like" }
);

condition.Concat = "and";

condition.AndCondition.Add(
new ConditionModel() { Field = "yyyy", Value = "yyy_SearchValue", Op = "=" }
);

condition.ToWhereExpression<T>();

 附加:配合前端使用更舒服


class Pagination{
    constructor(PageSize,PageIndex,Sort,SortType,TotalCount,keywords,cdition){
        this.PageSize=PageSize
        this.PageIndex=PageIndex
        this.Sort=Sort
        this.SortType=SortType
        this.TotalCount=TotalCount
        this.keywords=keywords
        if(cdition){
            if(cdition instanceof condition)
                this.cdition=cdition
            else
            {
                console.log('cdition 错误 请用 new condition');
            }
        }
    }
      toJSON() {
        let obj={
            __className: 'Pagination', 
            PageSize: this.PageSize, 
            PageIndex: this.PageIndex,
            Sort: this.Sort,
            SortType: this.SortType,
            TotalCount: this.TotalCount,
            keywords: this.keywords
        }
        if(this.cdition)
            obj.condition=this.cdition.toJSON()
        return obj;
      }
     
      static fromJSON(json) {
        return new Pagination(
            json.PageSize,
            json.PageIndex,
            json.Sort,
            json.SortType,
            json.TotalCount,
            json.keywords,
            json.cdition
            );
      }
}
class conditionItem{
    constructor(Field,Value,Op){
        this.Field=Field
        this.Value=Value
        this.Op=Op
    }
    toJSON(){
        let obj={
            __className: 'conditionItem', 
            Field: this.Field, 
            Value: this.Value,
            Op: this.Op,
        }
        return obj
    }
}

class condition{
    constructor(options){
        if(options.AndCondition)
        {
            if(!Array.isArray(options.AndCondition)){
                throw new Error('options.AndCondition 必须是conditionItem数组')
            }
            this.AndCondition=options.AndCondition
        }
        if(options.OrCondition)
        {
            if(!Array.isArray(options.OrCondition)){
                throw new Error('options.OrCondition 必须是conditionItem数组')
            }
            this.OrCondition=options.OrCondition
        }
        if(options.Concat)
         this.Concat=options.Concat
    }
    toJSON(){
        let obj={
            __className: 'condition'
        }
       
        if(this.AndCondition)
        { 
            obj.AndCondition=[]
            for (let item of this.AndCondition){
                obj.AndCondition.push(item.toJSON())
            }
        }
        if(this.OrCondition)
        {
             obj.OrCondition=[]
            for (let item of this.OrCondition){
                obj.OrCondition.push(item.toJSON())
            }
        }
        if(this.Concat)
            obj.Concat=this.Concat
        return obj;
    }
}
/**
var cond=new condition({
    AndCondition:[
        new conditionItem("name","此","="),
        new conditionItem("age","32","=")
    ],
    OrCondition:[]
})
var pagination=new Pagination(12,1,'id','asc',0,'',cond)
var s=pagination.toJSON()
console.log(JSON.stringify(s)) 
 */

export  {Pagination,condition,conditionItem}

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值