mikeobrien.net Curriculum Vitae Blog Labs
Monday, December 28, 2009

Today I had to write some code that had nullable parameters that could filter the results of a Linq query. At first I was doing “if” statements on the nullable parameters to determine if they needed to be applied. This was pretty verbose so I came up with a more succinct approach with conditional Linq extension methods.

First define conditional extension methods on IQueryable<>:

public static class IQueryableExtensions
{
    public static IQueryable<T> Where<T>(this IQueryable<T> query, bool condition, 
        System.Linq.Expressions.Expression<Func<T, bool>> predicate)
    {
        return condition ? query.Where(predicate) : query;
    }

    public static IQueryable<T> Take<T>(this IQueryable<T> query, bool condition, int count)
    {
        return condition ? query.Take(count) : query;
    }

    public static IQueryable<T> Skip<T>(this IQueryable<T> query, bool condition, int count)
    {
        return condition ? query.Skip(count) : query;
    }

    // ...
}

Then you get a nice fluent way to conditionally apply the parameters:

public List<Template> EnumerateTemplates(
    Guid accountId,
    int? startIndex,
    int? maxResults,
    Guid? groupId,
    bool? includeSubGroups,
    DateTime? olderThan,
    DateTime? newerThan)
{
    using (IRepository<Template> templates = Context.Current.Create<IRepository<Template>>())
    {
        var selectedTemplates = templates.
            Where(t => t.Account.Id == accountId).
            Where(groupId.HasValue, t => t.Group.Id == groupId.Value).
            Where(!groupId.HasValue && includeSubGroups.HasValue && 
                  !includeSubGroups.Value, t => t.Group == null).
            Where(olderThan.HasValue, t => t.Created < olderThan.Value).
            Where(newerThan.HasValue, t => t.Created > newerThan.Value).
            Take(maxResults.HasValue, maxResults.Value).
            Skip(startIndex.HasValue, startIndex.Value - 1);

        return selectedTemplates.ToList();
    }
}
C# | Linq | NHibernate
Name
E-mail
(will show your gravatar icon)
Home page

Comment (Some html is allowed: a@href@title, b, i, strike, strong, u) where the @ means "attribute." For example, you can use <a href="" title=""> or <blockquote cite="Scott">.  

Enter the code shown (prevents robots):

Live Comment Preview
Creative Commons License