LINQ: разделить, где или условия

Итак, у меня есть следующие условия

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

Я хочу разделить это на несколько строк в зависимости от того, пуста ли строка, например:

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

Если вы заметили, что я хочу добавить несколько условий ИЛИ, разделенных в зависимости от того, пустые строки Room, Course и Division или нет.

2 ответа

Решение

Есть несколько способов сделать это:

  1. Применить "где" к исходному запросу каждый раз, а затем Union() результирующие запросы.

    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. Делайте манипуляции с выражениями, чтобы объединить тела ваших лямбда-выражений вместе, OrElse выражения. (Сложно, если у вас уже нет библиотек, которые могли бы вам помочь: после объединения тел вам также придется пройти по дереву выражений, чтобы заменить выражения параметров. Это может стать затруднительным.

  3. Используйте такой инструмент, как PredicateBuilder, чтобы сделать №2 для вас.

.Where() предполагает логичный AND и, насколько я знаю, нет готового решения для этого. Если вы хотите отделить OR заявления, вы можете захотеть использовать Predicate Builder или Dynamic Linq.

You can create an extension method to conditionally apply the filter:

public static IQueryable<T> WhereIf<T>(
   this IQueryable<T> source, bool condition, 
   Expression<Func<T, bool>> predicate)
{
    return condition ? source.Where(predicate) : source;
}

And use it like this:

using static System.String;

...

var res = sessions
   .WhereIf(!IsNullOrEmpty(Division), y => y.session.SESSION_DIVISION.ToUpper().Contains(SearchContent))
   .WhereIf(!IsNullOrEmpty(Room), y => y.session.ROOM.ToUpper().Contains(SearchContent))
   .WhereIf(!IsNullOrEmpty(course), y => y.session.COURSE.ToUpper().Contains(SearchContent)));
Другие вопросы по тегам