我的枚举如下:
public enum BPLevel {
Normal = 1,
HighNormal = 2,
HypertensionStage1 = 3,
ModerateHypertensionStage2 = 4,
SeverHypertensionStage3 = 5,
} // BloodPressureLevel
我有以下分类:
我正在使用实体框架,我需要计算每个级别中有多少人:
IDictionary<BPLevel, Int32> stats = context
.Persons
.Select(x => new { PersonId = x.Person.Id, BPDiastolic = x.BPDiastolic, BPSystolic = x.BPSystolic })
.Count( ...
我的问题是如何在我的查询中应用此分类?
答案 0 :(得分:1)
我只想添加一个分配给函数调用结果的分类成员
IDictionary<BPLevel, Int32> stats = context
.Persons
.Select(x => new { PersonId = x.Person.Id, BPDiastolic = x.BPDiastolic,
BPSystolic = x.BPSystolic,
Classification = GetClassification(BPDiastolic, BPSystolic) })
.Count( ...
BPLevel GetClassification(int diastolic, int systolic)
{
...
}
对EF的查询有时候不喜欢在查询中发生的操作,因此您可能需要在ToList
之前执行Select
以将其放入内存(因此其对象的LINQ)
答案 1 :(得分:0)
我会在你的类中编写一个私有静态辅助函数,为你做分类并在你的投影中插入对该函数的调用。类似的东西:
private static BPLevel ClassifyBP(int diastolic, int systolic) {
// Appropriate switch statement here
}
然后您的选择投影看起来像:
.Select(x => new { PersonId = x.Person.Id,
BPDiastolic = x.BPDiastolic,
BPSystolic = x.BPSystolic,
BPLevel = ClassifyBP(x.BPDiastolic, x.BPSystolic) })
答案 2 :(得分:0)
使用GroupBy
语句,您可以将所有人分类到各自的BPLevel
,您只需要执行ToDictionary
并计算每个类别中的人数。因此
IDictionary<BPLevel, Int32> stats = context
.Persons
.Select(x => new { PersonId = x.Person.Id, BPDiastolic = x.BPDiastolic, BPSystolic = x.BPSystolic })
.AsEnumerable() // I'm not completely familiar with Entity Framework, so this line may be necessary to force evaluation to continue in-memory from this point forward
.GroupBy(p => ... // Test which returns a BPLevel)
.ToDictionary(g => g.Key, g => g.Count());
答案 3 :(得分:0)
我在这种情况下做的是在Person
public BPLevel BpLevel
{
get
{
if(Systolic >= 180)
return BPLevel.SeverHypertensionStage3
else if
...
}
}
然后我按
分组.ToList() // you need to execute against the DB before you call the helper property
.GroupBy(x => x.BPLevel)
.Select(x => /*moar data transformation
x is a collection of Person
x.Key, is the BPLevel*/ )
确保你执行ToList()
部分,否则在尝试将helper属性转换为SQL时可能会得到一个不受支持的异常
答案 4 :(得分:0)
另一种选择是选择具有BPLevel属性getter的具体类,为您进行分类:
public class PersonWithBP {
// other properties
public BPLevel BPClassification {
get {
// logic to calculate BPLevel
return bpLevel;
}
}
现在你的选择变为
.Select(x => new PersonWithBP() {}
答案 5 :(得分:0)
这不太好,但是计数查询将在数据库中执行。
var stats = context.Persons
.Select(x => new
{
Level = x.BPDiastolic < 85 && x.BPSystolic < 130
? BPLevel.Normal
: (x.BPDiastolic < 90 && x.BPSystolic < 140
? BPLevel.HighNormal
: (x.BPDiastolic < 100 && x.BPSystolic < 160
? BPLevel.HypertensionStage1)
: (x.BPDiastolic < 110 && x.BPSystolic < 180
? BPLevel.ModerateHypertensionStage2
: BPLevel.SeverHypertensionStage3)))
})
.GroupBy(x => x.Level)
.ToDictionary(x => x.Key, g => g.Count()) // execute in database
.Union(Enum.GetValues(typeof(BPLevel))
.OfType<BPLevel>()
.ToDictionary(x => x, x => 0)) // default empty level
.GroupBy(x => x.Key)
.ToDictionary(x => x.Key, x => x.Sum(y => y.Value)); // combine both