Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ: Split Where OR conditions

So I have the following where conditions

sessions = sessions.Where(y => y.session.SESSION_DIVISION.Any(x => x.DIVISION.ToUpper().Contains(SearchContent)) ||
                                                   y.session.ROOM.ToUpper().Contains(SearchContent) ||
                                                   y.session.COURSE.ToUpper().Contains(SearchContent));

I want to split this into multiple lines based on whether a string is empty for example:

if (!String.IsNullOrEmpty(Division)) {
    sessions = sessions.Where(y => y.session.SESSION_DIVISION.Any(x => x.DIVISION.ToUpper().Contains(SearchContent)));
}

if (!String.IsNullOrEmpty(Room)) {

    // this shoudl be OR
    sessions = sessions.Where(y => y.session.ROOM.ToUpper().Contains(SearchContent));
}

if (!String.IsNullOrEmpty(course)) {

    // this shoudl be OR
    sessions = sessions.Where(y => y.session.COURSE.ToUpper().Contains(SearchContent));
}

If you notice I want to add multiple OR conditions split based on whether the Room, course, and Division strings are empty or not.

like image 508
Eric Bergman Avatar asked Apr 15 '14 20:04

Eric Bergman


2 Answers

There are a few ways to go about this:

  1. Apply the "where" to the original query each time, and then Union() the resulting queries.

    var queries = new List<IQueryable<Session>>();
    if (!String.IsNullOrEmpty(Division)) {
        queries.Add(sessions.Where(y => y.session.SESSION_DIVISION.Any(x => x.DIVISION.ToUpper().Contains(SearchContent))));
    }
    
    if (!String.IsNullOrEmpty(Room)) {
    
        // this shoudl be OR
        queries.Add(sessions.Where(y => y.session.ROOM.ToUpper().Contains(SearchContent)));
    }
    
    if (!String.IsNullOrEmpty(course)) {
    
        // this shoudl be OR
        queries.Add(sessions.Where(y => y.session.COURSE.ToUpper().Contains(SearchContent)));
    }
    
    sessions = queries.Aggregate(sessions.Where(y => false), (q1, q2) => q1.Union(q2));
    
  2. Do Expression manipulation to merge the bodies of your lambda expressions together, joined by OrElse expressions. (Complicated unless you've already got libraries to help you: after joining the bodies, you also have to traverse the expression tree to replace the parameter expressions. It can get sticky. See this post for details.

  3. Use a tool like PredicateBuilder to do #2 for you.
like image 122
StriplingWarrior Avatar answered Nov 07 '22 22:11

StriplingWarrior


.Where() assumes logical AND and as far as I know, there's no out of box solution to do it. If you want to separate OR statements, you may want to look into using Predicate Builder or Dynamic Linq.

like image 35
Steven V Avatar answered Nov 07 '22 22:11

Steven V