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.
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.