I am creating a query to return some data from a database. I am passing in a list of ids that I want to filter on. If the filter list is null or empty I want to return all the things.
I have an extension method that lets me do this
query
is an IQueryable
, Ids
is a list of nullable ints (don't ask!) ListHasElements
is a method that returns true if the list is non-null and has something in it.
var filteredList = query.WhereIf(ListHasElements(Ids), s => Ids.Contains(s.Id.Value));
However when I build query
I use my prefered query syntax
var query = from a in dbContext.as
join b in dbContext.bs on a.Id.ToString() equals b.Id
join cin dbContext.cs on b.Id equals c.Id into bcJoin
from items in bcJoin.DefaultIfEmpty()
where b.Sent >= fromDate
where b.Sent <= toDate
select new{a=a.thing, b=b.thingy, q=items.q,Id=a.Id}
Then I have to insert the initial line to do my magic WhereIf filter. and finally a further select to group by and create my output object (code not shown!)
The extension method looks like this.
public static IQueryable<TSource> WhereIf<TSource>(this IQueryable<TSource> source, bool condition,
Expression<Func<TSource, bool>> predicate)
{
return condition ? source.Where(predicate) : source;
}
Can I use this method directly in my query syntax query?
You can't. The compiler takes well-known query syntax keywords and converts them to method syntax behind-the-scenes. It knows nothing of your custom extension and thus has no equivalent in query syntax. Note that other "built-in" linq functions have no query syntax equivalent:
Skip
Count
Take
Single
FirstOrDefault
Max
Although I would note that your extension is basically equivalent to
where !condition || predicate(b)