【问题标题】:Passing a parameter to a linq predicate将参数传递给 linq 谓词
【发布时间】:2013-09-23 19:38:20
【问题描述】:

我想写如下代码 -

    public IQueryable<Invoice> InvoiceFilterForMonthAndYear(DateTime? monthAndYear = null)
    {
        var invoices = _invoices.Where(MonthAndYearPredicate(monthAndYear);
        return invoices;
    }

    private bool MonthAndYearPredicate(Invoice invoice, DateTime? monthAndYear)
    {
        //code to check if the invoice start or end dates is from the falls in the month I am checking for
    }

但我不能使用这样的谓词,因为谓词只需要一个参数。

我知道我可以在 InvoiceFilterForMonthAndYear 中写一个 Where 子句来完成这项工作,但是 我想把比较的逻辑放到它自己的方法中。

【问题讨论】:

  • i =&gt; MonthAndYearPredicate(i, monthAndYear)
  • @user1 这将编译,但查询提供程序将无法处理。
  • 啊,全是 LTE。错过了标签。

标签: c# linq entity-framework linq-to-entities predicate


【解决方案1】:

如果你的比较方法返回一个表达式,它会起作用:

private Expression<Func<Invoice,bool>> MonthAndYearPredicate(
    DateTime? monthAndYear)
{
    return i => i.StartDate >= monthAndYear; // or whatever
}

在你的例子中被调用:

var invoices = _invoices.Where(MonthAndYearPredicate(monthAndYear));

或者您可以将逻辑提取到IQueryable&lt;Invoice&gt;的扩展方法中:

public static class QueryExtensions
{
    public static IQueryable<Invoice> WhereMonthAndYear(
        this IQueryable<Invoice> query, DateTime? monthAndYear)
    {
        return query.Where(i => i.StartDate >= monthAndYear); // or whatever
    }
}

这样称呼:

var invoices = _invoices.WhereMonthAndYear(monthAndYear);

请记住,在这两种情况下,您都必须使用 EF 可以转换为 SQL 的有效 LINQ-to-Entities 表达式。它只是使表达式可重用于不同的查询,但没有扩展其功能。

【讨论】:

    【解决方案2】:

    您将无法将逻辑提取到方法中。如果这样做,则方法调用产生的表达式树将没有足够的信息供查询提供程序生成查询。您需要内联逻辑,以便它最终出现在表达式树中。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-03-19
      • 2012-06-16
      • 1970-01-01
      • 2018-08-19
      • 2011-04-16
      相关资源
      最近更新 更多