将参数传递给 linq 谓词

本文关键字:谓词 linq 参数传递 | 更新日期: 2023-09-27 18:32:32

我想写如下代码 -

    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 子句来完成这项工作,但是我想将比较的逻辑放入自己的方法中。

将参数传递给 linq 谓词

如果您的比较方法返回表达式,则它有效:

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

像您的示例中一样调用:

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

或者你可以将逻辑提取到IQueryable<Invoice>的扩展方法中:

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 到实体表达式。它仅使表达式可重用于不同的查询,但不扩展其功能。

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