我有一个计划,必须收集任务状态与条件匹配的人员的ID:
有表人员,任务和时间表。相关字段为:
<ul>
<li>Grid Item</li>
<li>Grid Item</li>
<li>Grid Item</li>
<li>Grid Item</li>
<li>Grid Item</li>
<li>Grid Item</li>
</ul>
在这种情况下,人员具有计划任务,总共12个,每个任务都有一个计划,因此每个人在计划中有12行,每个计划有1个任务。时间表通常是几天,不会重叠。
任务可以具有6个不同的状态之一,其中2个是 StateX 和 StateEmpty 。
我需要使用ef和linq来收集在StateX中拥有2个最新Task的患者,或者在StateX中具有最新Task的那些患者,然后在StateEmpty中收集一个,然后在StateX中再次收集。因此,StateX中的两个最新任务或者StateX中的最新任务之间的一个StateEmpty。
例如:
Person.Id
Schedule.Id
Schedule.StartDate
Schedule.EndDate
Task.Id
Task.ScheduleId
Task.PersonId
Task.State
问题是我无法使用诸如entity.Tasks.Include(c => c.Schedules)之类的查询,该查询没有给我时间表以链接表。我可以使用的只是任务和计划的单独列表。这些查询中的dbcontext不同,并且使用不同的数据库连接检索数据,这是我无法更改的。
我可以做类似的事情:
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
...,并使用循环和ifs匹配条件并将“个人ID”收集到列表中。
但是,这似乎并不是我想解决问题的最佳方法。我想确保性能不是问题,并且代码清晰易读。
您将如何解决?
答案 0 :(得分:0)
也许您可以尝试这样的事情:
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};
放纵我没有测试它,但是这个想法在那里。
答案 1 :(得分:0)
感谢塞巴斯蒂安
您的示例使我找到了自己满意的解决方案,至少基于小规模测试,这是我想到的:
我刚刚添加了一个排序依据和一个分组依据以帮助处理结果。
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);
}
}