首页 > 解决方案 > 获取相关表数据匹配条件的人员ID

问题描述

我有一个方案,我必须收集任务状态与条件匹配的人员的 ID:

有表格人,任务和时间表。相关领域是:

Person.Id

Schedule.Id
Schedule.StartDate
Schedule.EndDate

Task.Id
Task.ScheduleId
Task.PersonId
Task.State

在这种情况下,Person 有计划的任务,总共 12 个,每个都有一个计划,因此每个人的计划中有 12 行,每个计划有 1 个任务。时间表通常长达几天,从不重叠。

任务可以有 6 种不同状态中的 1 种,其中 2 种是StateXStateEmpty

我需要收集 - 使用 ef 和 linq - 那些在 StateX 中有 2 个最新任务的患者,或者那些在 StateX 中有最新任务​​的患者,然后在 StateEmpty 中有一个,然后在 StateX 中再有一个。因此,StateX 中的 2 个最新任务或 StateX 中最新任务之间的一个 StateEmpty。

例如:

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

问题是我不能使用像entities.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 来匹配条件并将人员 ID 收集到列表中。

但这似乎不是我想要解决问题的最佳方法。我想确保性能不是问题,并且代码可读且清晰。

你会如何解决这个问题?

标签: c#entity-frameworklinq

解决方案


谢谢塞巴斯蒂安,

你的例子让我得到了一个我很满意的解决方案,至少基于小规模测试,这就是我想出的:

我刚刚添加了一个 order by 和一个 group by 来帮助处理结果。

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

推荐阅读