Получение идентификаторов лиц, для которых связанные данные таблицы соответствуют условию - PullRequest
0 голосов
/ 11 сентября 2018

У меня есть сценарий, в котором я должен собрать идентификаторы лиц, чьи состояния задач соответствуют условию:

Существуют таблицы 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, чтобы соответствовать условию и собрать идентификаторы лиц в список.

Но это не самое лучшее, что я хотел бы решить эту проблему.Я хотел бы убедиться, что производительность не является проблемой, а код читабелен и понятен.

Как бы вы решили это?

Ответы [ 2 ]

0 голосов
/ 11 сентября 2018

Спасибо, Себастьян,

Ваш пример привел меня к решению, которым я доволен, по крайней мере, на основе мелкомасштабного тестирования, вот что я придумал:

Я только что добавил заказ и группу, чтобы помочь обработать результат.

List<string> patientIds = new List<string>();
var schedules = scheduleEntities.schedules.Where(s => s.StartTime > somedate && s.EndDate < DateTime.Now).ToList();
var tasks = taskEntities.Tasks.ToList();

var items =
    from schedule in schedules
    join task in tasks on schedule.Id equals task.ScheduleId
    orderby schedule.StartTime descending
    select new { task.PersonId, schedule.StartTime, task.State };
var itemgroups = items.GroupBy(i => i.PersonId).ToList();

foreach (var item in itemgroups)
{
    if ((item.Count() >= 2 && (item.ElementAt(0).State == "StateX" && item.ElementAt(1).State == "StateX"))
        ||
        (item.Count() >= 3 && (item.ElementAt(0).State == "StateX" && item.ElementAt(1).State == "StateEmpty" && item.ElementAt(2).State == "StateX")))
    {
        patientIds.Add(item.Key);
    }
}
0 голосов
/ 11 сентября 2018

Может быть, вы можете попробовать что-то вроде этого:

var joinQuery =
    from schedule in scheduleEntities.Schedules
    join task in taskEntities.Tasks on schedule.Id equals task.ScheduleId
    where schedule.StartTime > somedate && schedule.EndDate < DateTime.Now &&  (task.State == StateX || task.State == StateEmpty)
    select new { PersonId = task.PersonId};

Будьте снисходительны, я не проверял, но идея есть.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...