【问题标题】:How can I build logic upon supplied logic in a LINQ-to-Entities Where expression?如何在 LINQ-to-Entities Where 表达式中根据提供的逻辑构建逻辑?
【发布时间】:2016-11-15 22:15:40
【问题描述】:

我经常在 LINQ for Entity Framework 中遇到一种模式,如果指定了字符串值,我会在其中添加 .Where 子句,例如:

IQueryable<Foo> query = Foos.AsQueryable()
if (!string.IsNullOrWhitespace(nameFilter)) query = query.Where(x => x.Name == name);
if (!string.IsNullOrWhitespace(addressFilter) != null) query = query.Where(x => x.Address == addressFilter );
if (!string.IsNullOrWhitespace(cityFilter) != null) query = query.Where(x => x.City == cityFilter );
// ...

我想清理它并避免重复过滤器。我想我可以创建一个扩展方法:

public static IQueryable<T> WhereEqualIfSpecified<T>(
    this IQueryable<T> query,
    Expression<Func<T, string>> fieldDelegate,
    string filterValue)
{
    return string.IsNullOrWhiteSpace(filterValue) 
        ? query 
        : query.Where(x => fieldDelegate(x) == filterValue);  // not valid, see question below
}

这样我就可以将代码改为:

IQueryable<Foo> query = Foos.AsQueryable()
    .WhereEqualIfSpecified(x => x.Name, nameFilter)
    .WhereEqualIfSpecified(x => x.Address, addressFilter)
    .WhereEqualIfSpecified(x => x.City, cityFilter)
    // ...
;

但我发现,在上面的 WhereEqualIfSpecified 方法中,fieldDelegate 必须编译为 Func() 才能针对实体源调用,这破坏了执行这些步骤的意义,这些步骤将在我原始代码中的数据库。

我错过了如何从fieldDelegate 创建一个可以进行比较的新Expression 的最后一步,而不仅仅是返回字符串值。这种方法会奏效吗?如何在WhereEqualIfSpecified 中设置必要的Expression 以允许LINQ-to-Entities 稍后执行?

【问题讨论】:

    标签: c# entity-framework linq expression-trees


    【解决方案1】:

    您在这里要做的是编写表达式。表达式与委托不同,编写起来有点复杂。 Here 是如何组合表达式的一种实现。一旦你有了Compose 方法,你就可以把你的扩展方法写成:

    public static IQueryable<T> WhereEqualIfSpecified<T>(
        this IQueryable<T> query,
        Expression<Func<T, string>> fieldExpression,
        string filterValue)
    {
        return string.IsNullOrWhiteSpace(filterValue) 
            ? query 
            : query.Where(fieldExpression.Compose(value => value == filterValue);
    }
    

    【讨论】:

    • 谢谢!它奏效了,我学到了很多关于使用表达式的知识。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多