动态构造一个表达式>不适合GreaterThen

本文关键字:Func bool GreaterThen 不适合 表达式 一个 动态 | 更新日期: 2023-09-27 17:50:14

你好,我有一个简单的查询实体框架:

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

现在我想把这个查询更改为更动态的东西。但我想改变的,不仅是常量(2005),还有我的列域(PublishedYear)。

我正在寻找几天如何动态构建一个Expression<Func<,>>。现在我找到了这个页面,我正试着这么做。到目前为止,我得到了这个:

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. nullable]没有定义二进制操作符GreaterThan。

p :
Book的列PublishedYear是实体框架类中的INT NULLint?

表达式w => w.PublishedYear > 2005为什么它一直说不存在这个操作?我该怎么修理它?

动态构造一个表达式<Func<T,bool>>不适合GreaterThen

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

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

如果PublishedYear的值NULL是允许的,但实际上没有出现,也许您可以将两个函数中value的参数类型更改为int?,并使用value.Value进行Expression.GreaterThan的比较。