У меня есть сценарий, в котором я должен собрать идентификаторы лиц, чьи состояния задач соответствуют условию:
Существуют таблицы Person, Task и Schedule.Соответствующие поля:
Person.Id
Schedule.Id
Schedule.StartDate
Schedule.EndDate
Task.Id
Task.ScheduleId
Task.PersonId
Task.State
В этом случае у человека есть запланированные задачи, всего 12, у каждого из которых есть расписание, поэтому 12 строк в расписании на человека, по 1 задаче на каждое расписание.Расписание обычно длится несколько дней и никогда не пересекается.
Задача может иметь 1 из 6 различных состояний, 2 из которых StateX и StateEmpty .
Мне нужно собрать - используя ef и linq - тех пациентов, у которых есть 2 последние задачи в StateX, или тех пациентов, у которых есть последняя задача в StateX, затем один в StateEmpty, а затем еще один в StateX.Таким образом, либо 2 последние задачи в StateX, либо один StateEmpty между последними задачами в StateX.
Например:
Task.Id Task.State Schedule times
1 StateX 2018-09-01 - 2018-09-05
2 StateX 2018-08-01 - 2018-08-05 -- matches
3 StateX 2018-09-01 - 2018-09-05
4 StateZ 2018-08-01 - 2018-08-05 -- doesn't match
5 StateX 2018-09-01 - 2018-09-05
6 StateEmtpy 2018-08-01 - 2018-08-05
7 StateZ 2018-07-01 - 2018-07-05 -- doesn't match
8 StateX 2018-09-01 - 2018-09-05
9 StateEmpty 2018-08-01 - 2018-08-05
10 StateX 2018-07-01 - 2018-07-05 -- matches
Проблема в том, что я не могу использовать запрос, подобный entity.Tasks.Include (c => c.Schedules), запрос не дает мне Расписания для ссылкистолы.Все, с чем я могу работать, это отдельные списки задач и расписаний.Dbcontext отличается в этих запросах, и данные извлекаются с использованием разных соединений с БД, это то, что я не могу изменить.
Я могу сделать что-то вроде:
var schedules = scheduleEntities.Schedules.Where(s => s.StartTime > somedate && s.EndDate < DateTime.Now).ToList();
var ids = schedules.Select(s => s.Id).ToList();
var tasks = taskEntities.Tasks.Where(t => ids.Contains(t.ScheduleId) && (t.State == StateX || t.State == StateEmpty)).ToList();
... и использовать циклы иifs, чтобы соответствовать условию и собрать идентификаторы лиц в список.
Но это не самое лучшее, что я хотел бы решить эту проблему.Я хотел бы убедиться, что производительность не является проблемой, а код читабелен и понятен.
Как бы вы решили это?