我想编写过滤控件,它采用对象类型 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;
}
有帮助吗?

解决方案

这里的反思不是问题; 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的问题。

其他提示

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

https://github.com/PoweredSoft/DynamicLinq

也可以在nuget上下载:

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

你可以简单地做

query.Where("FirstName", ConditionOperators.Equal, "David");
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top