为Linq构建动态表达式使用PropertyInfo和值

时间:2015-02-20 11:23:46

标签: c# asp.net .net linq linq-to-entities

正如标题所述,我想使用propertyInfo和值构建动态表达式。

目前我有类似的东西

public static IQueryable<T> WhereValueEquals<T>(this IQueryable<T> q, FieldFor fieldFor, string fieldValue) 
        where T : ModuleData
    {
        switch (fieldFor)
        {
            case FieldFor.Name:
                return q.Where(e => e.Name == fieldValue);
            case FieldFor.Reference:
                return q.Where(e => e.Reference == fieldValue);
            case FieldFor.Text0:
                return q.Where(e => e.Reference == fieldValue);

            default:
                return q;
        }
    }

现在案例陈述只会越来越长,但在发展的早期阶段这很好。

现在,使用FieldFor枚举,我可以使用我已编写的扩展来获取propertyInfo。那么我如何使用传入的字符串值和propertyInfo

从WhereValueEquals返回IQueryable

到目前为止我已经

public static IQueryable<T> WhereValueEquals<T>(this IQueryable<T> q, FieldFor fieldFor, string fieldValue) 
    where T : ModuleData
{
    PropertyInfo propertyInfo = typeof(T).GetFieldProperties().GetPropertyByFieldFor(fieldFor);            

    //return q.Where(expression);
}

1 个答案:

答案 0 :(得分:1)

在某些时候我不得不做类似的事情,Stackoverflow上有大量代码向您展示如何构建表达式构建器。那么这是我的POC,希望它可以帮助你

void Main()
{
    var ops  = new List<Ops>
    { 
        new Ops
        {
            //OperandType = typeof(string), 
            OpType=OpType.Equals, 
            OperandName = "Name", 
            ValueToCompare = "MM"
        },
        new Ops
        {
            //OperandType = typeof(int), 
            OpType=OpType.Equals, 
            OperandName = "ID", 
            ValueToCompare = 1
        },
    };
    var testClasses = new List<TestClass>
    {
        new TestClass { ID =1, Name = "MM", Date = new DateTime(2014,12,1)},
        new TestClass { ID =2, Name = "BB", Date = new DateTime(2014,12,2)}
    };

    var funct = ExpressionBuilder.BuildExpressions<TestClass>(ops);
    foreach(var item in testClasses.Where(funct))
    {
        Console.WriteLine("ID " +item.ID);
        Console.WriteLine("Name " +item.Name);
        Console.WriteLine("Date" + item.Date);
    }
}

//在此定义其他方法和类

public enum OpType
{
    Equals
}

public class Ops
{
    //public Type OperandType {get; set;}

    public OpType OpType {get; set;}

    public string OperandName {get;set;}

    public object ValueToCompare {get;set;}
}

public class TestClass
{   
    public int ID {get;set;}
    public string Name {get; set;}
    public DateTime Date {get;set;}
}

public class ExpressionBuilder
{
    public static Func<T,bool> BuildExpressions<T>( List<Ops> opList)
    {
        Expression currentExpression= null;
        var parameter = Expression.Parameter(typeof(T), "prop");
        for(int i =0; i< opList.Count; i++)
        {
            var op =  opList[i];
            Expression innerExpression = null;
            switch(op.OpType)
            {
                case OpType.Equals :
                {
                    var innerParameter = Expression.Property(parameter,op.OperandName);
                    var ConstExpression = Expression.Constant(op.ValueToCompare);
                    innerExpression = Expression.Equal(innerParameter, ConstExpression);
                    break;
                }
            }

            if (i >0)
            {
                currentExpression = Expression.And(currentExpression, innerExpression);
            }
            else
            {
                currentExpression = innerExpression;
            }
        }
        var lambdaExpression = Expression.Lambda<Func<T,bool>>(currentExpression, new []{parameter});
        Console.WriteLine(lambdaExpression);
        return lambdaExpression.Compile() ;
    }
}