生成表达式<>以通过任意属性进行过滤

问题描述 投票:2回答:2

我想编写过滤控件,它采用对象类型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;
}
c# linq dynamic properties filtering
2个回答
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)非常方便 - 否则你可能会遇到null的问题。


0
投票

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

https://github.com/PoweredSoft/DynamicLinq

哪个也应该可以在nuget上下载:

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

你可以干脆做

query.Where("FirstName", ConditionOperators.Equal, "David");
© www.soinside.com 2019 - 2024. All rights reserved.