Friday, March 07, 2008
« Convert an array of type string to type ... | Main | Source Control and the Bin folder »

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;
}

kick it on DotNetKicks.com   Friday, March 07, 2008 8:29:01 AM (Pacific Standard Time, UTC-08:00)  #    Disclaimer  |  Comments [1]  |  Related posts:
TextBox MaxLength from LINQ Meta Data

Monday, April 21, 2008 6:35:43 AM (Pacific Standard Time, UTC-08:00)
This is a great practical little example of using extension methods. Thanks for the code!
york
Name
E-mail
Home page

Comment (Some html is allowed: a@href@title, strike) 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