Выражение LINQ для фильтрации

#c# #entity-framework #linq

Вопрос:

У меня есть следующее LINQ выражение , в котором я выбираю Courses , Students которое принадлежит этому Course , затем School «s», куда Student идет «s». Следующее выражение LINQ работает нормально.

Однако мне нужно продолжить, отфильтровать его там, где мне нужно, чтобы получить Students с City == 'Colarado' помощью . Как я могу изменить следующий LINQ в соответствии с моим вариантом использования.

      _dbContext.Courses
         .Where(c => c.Id == Id)
         .Include(c => c.Students)
             .ThenInclude(c => c.Schools)
         .OrderByDescending(c => c.Id)
         .ToListAsync();
 

Ответ №1:

Если вам нужны все курсы и только для фильтрации студентов — начиная с EF Core 5.0, вы можете использовать отфильтрованные, включая:

  _dbContext.Courses
     .Where(c => c.Id == Id)
     .Include(c => c.Students.Where(s => s.City == "Colarado"))
         .ThenInclude(c => c.Schools)
     .OrderByDescending(c => c.Id)
     .ToListAsync(); 
 

Комментарии:

1. OP: Обязательно прочитайте документ об этой функции, так как есть некоторые предостережения, которые следует учитывать. Если в вашем DbContext отслеживаются какие-либо связанные учащиеся для связанного курса из предыдущих запросов, эти учащиеся все равно могут быть возвращены для курса, даже если они не соответствуют условию фильтра. В идеале экземпляры DbContext, использующие эту функцию, должны выполнять AsNoTracking() запросы только во избежание такой возможности. Я бы предположил, что у этой функции в ядре 5 EF были некоторые споры между потенциальной полезностью и нарушением полного/завершенного состояния сущности. Я расколот, обычно это подается проекцией.

Ответ №2:

Вы можете выполнить фильтр в Where методе.

 _dbContext.Courses
     .Where(c => c.Id == Id amp;amp; c.Students.All(s => s.City == "Colarado"))
     .Include(c => c.Students)
         .ThenInclude(c => c.Schools)
     .OrderByDescending(c => c.Id)
     .ToListAsync();