【问题标题】:Dynamically constructing an Expression<Func<T,bool>> doesn't work for GreaterThen动态构造 Expression<Func<T,bool>> 不适用于 GreaterThen
【发布时间】:2014-03-14 15:56:53
【问题描述】:

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

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

现在我想将此查询更改为更动态的内容。但我想改变,不仅是常量值(2005),还有我的列字段(PublishedYear)。

我正在寻找几天如何动态构建Expression&lt;Func&lt;,&gt;&gt;。现在我找到了这个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
我在表Book 的列PublishedYear 是实体框架类中的INT NULLint?

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

【问题讨论】:

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


    【解决方案1】:

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

    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】:

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

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多