3

I want to write code like the following -

    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
    }

But I can't use a predicate like that because the predicate expects just one parameter.

I know I could write a Where clause in InvoiceFilterForMonthAndYear to do the work, but I want to put the logic for the comparison into its own method.

4

2 回答 2

5

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

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

于 2013-09-23T21:08:02.053 回答
-1

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

于 2013-09-23T19:40:48.027 回答