使用反射比较泛型/动态linq谓词中的子属性

时间:2012-11-05 17:37:55

标签: linq generics reflection predicate predicatebuilder

我必须为Entity Framework Linq查询一般构建比较谓词。我正在使用反射,并且能够毫无困难地构建单级Lambda表达式。然而,我开始陷入困境的是我有一个有关系的实体

public class Parent {
    public virtual Child child { get; set; }
    .... Other Stuff...
}

public class Child {
    public int property { get; set; }
    public virtual Parent parent { get; set; }
    .... Other Stuff.....
}

我怎样才能将“Child.property”传递给Reflection以便能够创建一个lambda表达式来比较并提出类似于item =>的lambda表达式。 item.Child.property == value?

2 个答案:

答案 0 :(得分:3)

我认为你正在寻找这个:

ParameterExpression parameter = Expression.Parameter(typeof(Parent), "item");
Expression child = Expression.PropertyOrField(parameter, "child");
Expression childProperty = Expression.PropertyOrField(child, "property");
int value = 1;
Expression comparison = Expression.Equal(childProperty, Expression.Constant(value));

Expression<Func<Parent, bool>> lambda = Expression.Lambda<Func<Parent, bool>>(comparison, parameter);


var sample = new[] { new Parent() { child = new Child() { property = 1 } } };
var result = sample.Where(lambda.Compile());

答案 1 :(得分:3)

我假设你想要一个支持嵌套属性的通用解决方案:

public Expression buildLambda(Type startingType, string propertyPath, object value) {

  var parameter=Expression.Parameter(startingType,"item");
  var valueExpression = Expression.Constant(value);
  var propertyExpression=propertyPath.Split('.').Aggregate(parameter,(Expression parent,string path)=>Expression.Property(parent,path));
  return Expression.Lambda(Expression.Equal(propertyExpression,valueExpression),parameter);
}