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(); } }
Remember Me
a@href@title, b, i, strike, strong, u