动态构造表达式<func <t,bool>&gt;不适用于GreaterThen </func <t,bool>

时间:2014-03-14 15:56:53

标签: c# entity-framework entity-framework-4 expression

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

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。

  

PS
表格PublishedYear的{​​{1}}列在实体框架类中为BookINT NULL

表达式int?为什么它一直说这个操作不存在?我该如何解决?

2 个答案:

答案 0 :(得分: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);
}

现在这样做有效:

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

......这是C#代码隐含的内容。

答案 1 :(得分:0)

如果NULL的值PublishedYear被允许但实际上没有发生,也许您可​​以将两个函数中的参数类型value更改为int?并使用{ {1}}进行比较{1}}。