生成表达式<>用于按任意属性过滤

时间:2009-09-11 12:39:55

标签: c# linq dynamic properties filtering

我想编写过滤控件,它采用对象类型T和属性名称,并返回Expression<Func<T, bool>>来检查传递属性的值。我不想使用反射,因为我担心EF不能使用这些表达式。我不能使用委托,因为C#没有属性的委托。我能做什么?也许我应该使用不同的方法来编写这些控件?

这是我使用反射的第一种方法:

public string FilteringField { get; set; }
public Expression<Func<T, bool>> GetFilterExpression()
{
  if (cmbValue.SelectedIndex == 1)
    return (o => (bool)typeof(T).GetProperty(FilteringField).GetValue(o, null));
  if (cmbValue.SelectedIndex == 2)
    return (o => !(bool)typeof(T).GetProperty(FilteringField).GetValue(o, null));
  return null;
}

2 个答案:

答案 0 :(得分:3)

这里的反思不是问题; EF甚至无法注意到差异。顺便说一句,委托方法是非首发的(因为你提到EF);最终,它是这样的:

public static IQueryable<T> Where<T>(this IQueryable<T> query,
    string propertyName, object value)
{
    PropertyInfo prop = typeof(T).GetProperty(propertyName);
    var param = Expression.Parameter(typeof(T), "x");
    var body = Expression.Equal(
        Expression.Property(param, prop),
        Expression.Constant(value, prop.PropertyType)
        );
    var predicate = Expression.Lambda<Func<T, bool>>(body, param);
    return query.Where(predicate);
}

请注意,Expression.PropertyOrField(propertyName)可以让您更轻松;我之前没有使用它的原因是在创建常量时知道成员类型(prop.PropertyType)非常方便 - 否则你可能会遇到空值问题。

答案 1 :(得分:0)

我知道这是一个陈旧的答案,但如果有人看到这个我已经建立了这个项目:

https://github.com/PoweredSoft/DynamicLinq

也可以在nuget上下载:

https://www.nuget.org/packages/PoweredSoft.DynamicLinq

你可以简单地做

query.Where("FirstName", ConditionOperators.Equal, "David");