动态构造Expression <Func <T,bool >>不适用于GreaterThen

Jon*_*zzi 1 c# expression entity-framework entity-framework-4

嗨,我在Entity Framework中有一个简单的查询:

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

现在我想将此查询更改为更动态的内容.但我想改变,不仅是常量值(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);
}
Run Code Online (Sandbox Code Playgroud)

但在第15行(var body = Expression.Greater...)中抛出异常:

没有为类型'System.Nullable`1 [System.Int32]'和'System.Int32'定义二元运算符GreaterThan.

PS:
PublishedYear的表的列BookINT NULLint?在实体框架类中.

这个表达式w => w.PublishedYear > 2005为什么一直说这个操作不存在?我该如何解决?

Jon*_*eet 5

问题是可空性.你可能只需要从值到属性类型添加转换表达式就可以了:

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);
}
Run Code Online (Sandbox Code Playgroud)

现在这有效地做了:

w => w.PublishedYear > (int?) 2005
Run Code Online (Sandbox Code Playgroud)

...这是C#代码隐式执行的操作.