代码之家  ›  专栏  ›  技术社区  ›  Jonny Piazzi

动态构造表达式<Func<T,bool>>不适用于GreaterThen

  •  1
  • Jonny Piazzi  · 技术社区  · 10 年前

    嗨,我在实体框架中有一个简单的查询:

    using (var db = new BookstoreContext())
    {
        return db.Book
            .Where(w => w.PublishedYear > 2005)
            .ToList();
    }
    

    现在我想将这个查询更改为更动态的查询。但我想改变的不仅仅是常量( 2005 )还有我的列字段( PublishedYear ).

    我几天都在寻找如何动态构建 Expression<Func<,>> 。现在我找到了这个 page 我正在努力做到这一点。到目前为止,我得出的结论是:

    public IEnumerable<Book> GetBooksGreaterThan(string columnName, object value)
    {
        using (var db = new BookstoreContext())
        {
            return  db.Book
                .Where(GreaterThan(columnName, value))
                .ToList();
        }
    }
    
    public Expression<Func<Book, bool>> GreaterThan(string columnName, object value)
    {
        var param = Expression.Parameter(typeof(Book), "w");
        var property = Expression.PropertyOrField(param, columnName);
        var body = Expression.GreaterThan(property, Expression.Constant(value));
    
        return Expression.Lambda<Func<Book, bool>>(body, param);
    }
    

    但在第15行( var body = Expression.Greater... )引发异常:

    未为类型“System.Nullable `1[System.Int32]”和“System.Int32”定义二进制运算符GreaterThan。

    附言 :
    我的专栏 发布年份 桌子上的 Book INT NULL int? 在实体框架类中。

    表达式 w => w.PublishedYear > 2005 那么为什么它一直说不存在这个操作呢?我该如何修复它?

    2 回复  |  直到 7 年前
        1
  •  5
  •   Jon Skeet    10 年前

    问题是可为空性。您可能只需添加一个从值到属性类型的转换表达式即可:

    public Expression<Func<Book, bool>> GreaterThan(string columnName, object value)
    {
        var param = Expression.Parameter(typeof(Book), "w");
        var property = Expression.PropertyOrField(param, columnName);
        var propertyType = typeof(Book).GetProperty(columnName).PropertyType;
        var body = Expression.GreaterThan(property,
             Expression.Convert(Expression.Constant(value), propertyType));
    
        return Expression.Lambda<Func<Book, bool>>(body, param);
    }
    

    这现在有效地做到了:

    w => w.PublishedYear > (int?) 2005
    

    …这就是C#代码隐式执行的操作。

        2
  •  0
  •   BenMorel lsalamon    10 年前

    如果值 NULL 对于 PublishedYear 是允许的,但实际上不发生,也许您可以更改参数的类型 value 在这两种功能中 int? 和使用 value.Value 用于中的比较 Expression.GreaterThan .