正如标题所述,我想使用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);
}
答案 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() ;
}
}