I find myself repeating the same little code pattern time after time when building a LINQ expression based on a number of optional filtering criteria. Using standard if statements seems a bit verbose to me.
if (SearchControlMain.CategoryID.HasValue)
query = query.Where(q => q.CategoryID == SearchControlMain.CategoryID);
if (SearchControlMain.TypeID.HasValue)
query = query.Where(q => q.TypeID == SearchControlMain.TypeID);
if (SearchControlMain.PostingID.HasValue)
query = query.Where(q => q.PostingID == SearchControlMain.PostingID);
Completely inlining the if statements doesn't do much for readability.
if (SearchControlMain.CategoryID.HasValue) query = query.Where(q => q.CategoryID == SearchControlMain.CategoryID);
if (SearchControlMain.TypeID.HasValue) query = query.Where(q => q.TypeID == SearchControlMain.TypeID);
if (SearchControlMain.PostingID.HasValue) query = query.Where(q => q.PostingID == SearchControlMain.PostingID);
So I created a couple of quick extension methods on both the IEnumerable and IQueryable forms of Where. I named my new extension WhereIf but I struggled a bit as to whether to name it just Where and wind up with an overload.
Now you can code:
query = query.WhereIf(SearchControlMain.CategoryID.HasValue, q => q.CategoryID == SearchControlMain.CategoryID);
query = query.WhereIf(SearchControlMain.TypeID.HasValue, q => q.TypeID == SearchControlMain.TypeID);
query = query.WhereIf(SearchControlMain.PostingID.HasValue, q => q.PostingID == SearchControlMain.PostingID);
Here are the extension methods:
public static IEnumerable<TSource> WhereIf<TSource>(this IEnumerable<TSource> source, bool condition, Func<TSource, bool> predicate)
{
if (condition)
return source.Where(predicate);
else
return source;
}
public static IEnumerable<TSource> WhereIf<TSource>(this IEnumerable<TSource> source, bool condition, Func<TSource, int, bool> predicate)
{
if (condition)
return source.Where(predicate);
else
return source;
}
public static IQueryable<TSource> WhereIf<TSource>(this IQueryable<TSource> source, bool condition, Expression<Func<TSource, bool>> predicate)
{
if (condition)
return source.Where(predicate);
else
return source;
}
public static IQueryable<TSource> WhereIf<TSource>(this IQueryable<TSource> source, bool condition, Expression<Func<TSource, int, bool>> predicate)
{
if (condition)
return source.Where(predicate);
else
return source;
}