Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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.

like image 639
tom Avatar asked Oct 27 '25 13:10

tom


1 Answers

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.

like image 123
Slauma Avatar answered Oct 29 '25 02:10

Slauma



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!