Search code examples
c#linqlinq-to-entitieslinq-query-syntax

How can I use this extension method in a linq to entities query using query syntax?


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?


Solution

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

    Although I would note that your extension is basically equivalent to

    where !condition || predicate(b)