代码之家  ›  专栏  ›  技术社区  ›  wRAR

生成表达式<>以按任意属性筛选

  •  2
  • wRAR  · 技术社区  · 16 年前

    我要编写采用对象类型的筛选控件 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 回复  |  直到 7 年前
        1
  •  3
  •   Marc Gravell    16 年前

    反思在这里不是问题,英孚甚至不会注意到区别。顺便说一句,委托方法是不起作用的(因为你提到了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 )创建常量时-否则可能会遇到空值问题。

        2
  •  0
  •   David Lebee    7 年前

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

    https://github.com/PoweredSoft/DynamicLinq

    在Nuget上也可以下载:

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

    你也可以这么做

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