在此示例中,类IcdPatient
表示Patient表(本示例中未显示)与查找表Icd
之间的多对多关系。
public class IcdPatient
{
public int PatientId { get; set; }
public int ConditionCode { get; set; }
public static List<IcdPatient> GetIcdPatientList()
{
return new List<IcdPatient>()
{
new IcdPatient { PatientId = 100, ConditionCode = 111 },
new IcdPatient { PatientId = 100, ConditionCode = 222 },
new IcdPatient { PatientId = 200, ConditionCode = 111 },
new IcdPatient { PatientId = 200, ConditionCode = 222 },
new IcdPatient { PatientId = 3, ConditionCode = 222 },
};
}
}
public class Icd
{
public int ConditionCode { get; set; }
public string ConditionName { get; set; }
public static List<Icd> GetIcdList()
{
return new List<Icd>()
{
new Icd() { ConditionCode =111, ConditionName ="Condition 1"},
new Icd() { ConditionCode =222, ConditionName ="Condition 2"},
};
}
}
我希望用户能够输入他们想要的任意数量的条件,并获得一个LINQ对象,告诉他们有多少PatientId
s满足该查询。我想出了:
List<string> stringFilteredList = new List<string> { "Condition 1", "Condition 2" };
List<int> filteringList = new List<int> { 111,222 };
var manyToMany = IcdPatient.GetIcdPatientList();
var icdList = Icd.GetIcdList();
/*Working method without joining on the lookup table*/
var grouped = from m in manyToMany
group m by m.PatientId into g
where g.Count() == filteringList.Distinct().Count()
select new
{
PatientId = g.Key,
Count = g.Count()
};
/*End*/
foreach (var item in grouped)
{
Console.WriteLine(item.PatientId);
}
让我们说IcdPatient
在两个字段都有一个复合主键,因此我们知道每一行都是唯一的。如果我们在filteringList
中找到不同数量的条目并计算PatientId
出现的次数,则表示我们找到了所有具有所有条件的人。因为代码可能是深奥的,我想做类似的事情
让用户表在Icd类型的ConditionName
中执行相同的操作。我没有这么多地使用LINQ而且我已经收集了:
List<int> filteringList = new List<int> { 111,222 };
List<string> stringFilteredList= new List<string>{"Condition 1","Condition 2" };
filteringList.Distinct();
var manyToMany = IcdPatient.GetIcdPatientList();
var icdList = Icd.GetIcdList();
/*Working method without joining on the lookup table*/
var grouped = from m in manyToMany
join i in icdList on
m.ConditionCode equals i.ConditionCode
//group m by m.PatientId into g
group new {m,i} by new { m.ConditionCode }into g
where g.Count() == filteringList.Distinct().Count()
select new
{
Condition = g.Key.ConditionCode
};
/*End*/
但无法正常工作。这基本上是我第一次查询时的联接,但我没有得到我需要分组的内容。
答案 0 :(得分:0)
在这种情况下,您不需要对任何内容进行分组,只需使用连接和包含:
List<string> stringFilteredList= new List<string>{"Condition 1","Condition 2" };
var patients =
from icd in Icd.GetIcdList()
join patient in IcdPatient.GetIcdPatientList() on icd.ConditionCode equals patient.ConditionCode
where stringFilteredList.Contains(icd.ConditionName)
select patient.PatientId;
答案 1 :(得分:0)
假设IcdPatient在两个字段上都有一个复合主键,因此我们知道每一行都是唯一的。如果我们在filteringList中找到不同数量的条目并对PatientId显示的次数进行计数,那意味着我们找到了所有具有所有条件的人。因为代码可能是深奥的,所以我想做一些事情,比如让类型为Icd的ConditionName中的用户表并执行相同的操作。
我相信你在问:
给定一个
ConditionCode
列表,返回PatientId
个列表,其中每个病人都有列表中的所有条件。
在这种情况下,最简单的方法是按Id分组您的IcdPatients表,以便我们可以通过查看一次来告诉患者的每个条件。然后我们检查我们正在寻找的每个ConditionCode
是否在该组中。在代码中,它看起来像:
var result = IcdPatient.GetIcdPatientList()
// group up all the objects with the same PatientId
.GroupBy(patient => patient.PatientId)
// gather the information we care about into a single object of type {int, List<int>}
.Select(patients => new {Id = patients.Key,
Conditions = patients.Select(p => p.ConditionCode)})
// get rid of the patients without every condition
.Where(conditionsByPatient =>
conditionsByPatient.Conditions.All(condition => filteringList.Contains(condition)))
.Select(conditionsByPatient => conditionsByPatient.Id);
在查询格式中,如下所示:
var groupedInfo = from patient in IcdPatient.GetIcdPatientList()
group patient by patient.PatientId
into patients
select new { Id = patients.Key,
Conditions = patients.Select(patient => patient.ConditionCode) };
var resultAlt = from g in groupedInfo
where g.Conditions.All(condition => filteringList.Contains(condition))
select g.Id;
修改:如果您还想让您的用户指定ConditionName
而不是ConditionId
,那么只需将其从一个转换为另一个,将结果存储在filteringList
中,就像这样:
var conditionNames = // some list of names from the user
var filteringList = Icd.GetIcdList().Where(icd => conditionNames.Contains(icd.ConditionName))
.Select(icd => icd.ConditionCode);