C# 按范围对值进行分类

C# 按范围对值进行分类,c#,entity-framework,C#,Entity Framework,我的列举如下: public enum BPLevel { Normal = 1, HighNormal = 2, HypertensionStage1 = 3, ModerateHypertensionStage2 = 4, SeverHypertensionStage3 = 5, } // BloodPressureLevel 我有以下分类: 我正在使用实体框架,我需要计算每个级别中有多少人: IDictionary<BPLevel, Int32> sta

我的列举如下:

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( ...
IDictionary stats=context
.人
.Select(x=>new{PersonId=x.Person.Id,bpdestromic=x.bpdestromic,BPSystolic=x.BPSystolic})
.Count(。。。

我的问题是如何在查询中应用此分类?

我只想添加一个分配给函数调用结果的分类成员

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)
{
    ...
}
IDictionary stats=context
.人
.Select(x=>new{PersonId=x.Person.Id,bpdisplastic=x.bpdisplastic,
BPSystolic=x.BPSystolic,
分类=GetClassification(舒张压、收缩压)}
.Count(。。。
BPL水平分级(舒张内压、收缩内压)
{
...
}

对EF的查询有时不喜欢查询内部发生的操作,因此您可能需要在
Select
之前执行
ToList
,以将其放入内存中(因此它的LINQ是对象).

我会在类中编写一个私有静态帮助函数,为您进行分类,并在投影中插入对该函数的调用。类似于:

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) })
使用语句可以将每个人分类到各自的
BPLevel
,这一点您只需要执行一个测试并计算每个类别中的人数

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());
IDictionary stats=context
.人
.Select(x=>new{PersonId=x.Person.Id,bpdestromic=x.bpdestromic,BPSystolic=x.BPSystolic})
.AsEnumerable()//我对实体框架不太熟悉,因此这一行可能需要强制计算从现在开始在内存中继续
.GroupBy(p=>…//返回BPLevel的测试)
.ToDictionary(g=>g.Key,g=>g.Count());

在这种情况下,我要做的是在
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*/ )

请确保执行该操作,否则当它尝试将帮助器属性转换为SQL时,可能会出现不受支持的异常。另一个选项是选择到一个具体类中,该类具有为您进行分类的BPLevel属性getter:

public class PersonWithBP {

  // other properties

  public BPLevel BPClassification {
    get { 
      // logic to calculate BPLevel
      return bpLevel;
   }

}
现在您的选择变成

.Select(x => new PersonWithBP() {}

这并不漂亮,但计数查询将在数据库中执行

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
var stats=context.Persons
.选择(x=>new
{
水平=舒张压<85,收缩压<130
?BPL水平。正常
:(舒张压<90和收缩压<140
?BPLevel.HighNormal
:(舒张压<100和收缩压<160
?血压水平。高血压状态1)
:(舒张压<110和收缩压<180
?BPLevel.mediatehypertensionstage2
:BPLevel.SeverHypertensionStage3)
})
.GroupBy(x=>x.Level)
.ToDictionary(x=>x.Key,g=>g.Count())//在数据库中执行
.Union(Enum.GetValues(typeof(BPLevel))
第()类
.ToDictionary(x=>x,x=>0))//默认为空级别
.GroupBy(x=>x.Key)
.ToDictionary(x=>x.Key,x=>x.Sum(y=>y.Value));//将两者结合起来

你能发布
context.Persons的班级成员吗?
?我很高兴听到下层选民对我的方法/帖子有什么问题。