tom
tom

Reputation: 1822

Passing a parameter to a linq predicate

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.

Upvotes: 4

Views: 6558

Answers (2)

Slauma
Slauma

Reputation: 177153

It works if your method for comparison returns an expression:

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

To be called like in your example:

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

Or you could extract the logic into an extension method of 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
    }
}

To be called like so:

var invoices = _invoices.WhereMonthAndYear(monthAndYear);

Keep in mind that in both cases you have to use valid LINQ-to-Entities expressions that EF can translate into SQL. It only makes the expressions reusable for different queries but does not extend its capabilities.

Upvotes: 7

Servy
Servy

Reputation: 203824

You won't be able to extract the logic out into a method. If you do, then the expression tree that results from the method call won't have enough information for the query provider to generate the query. You need to inline the logic so that it all ends up in the expression tree.

Upvotes: -2

Related Questions