LINQ 按类型和日期只获取四个对象

Get only four objects by type and date LINQ

我是编程新手,正在寻找任何建议。

我有一份门诊病人名单,每个病人都有以下类型之一:“儿童”、“青少年”、“成人”、“老年”,还有看医生的日期。

从患者列表中获取的问题只有四名患者,每种类型一名患者,并且具有最后一次就诊的最新日期。

我可以通过对数据库的四个单独请求来做到这一点。

var childPatient = await db.patientsOfClinic.Where(x => x.TypeOfPatient == "child").OrderByDescending(x => x.UploadedDate).FirstOrDefaultAsync();

但是需要一个请求到db来处理

尝试过这样的请求,但不正确。

var patientsOfClinic = await db.patientsOfClinic.Where(x => x.ClinicId == clinicId && x.TypeOfPatient == "child" && x.TypeOfPatient == "teenager" && x.TypeOfPatient == "adult" && x.TypeOfPatient == "oldage").OrderByDescending(y => y.UploadedDate).ToListAsync();

感谢任何建议。

此查询需要分组并加入该组。

// make reusable filtered set
var filtered = db.patientsOfClinic.Where(p => x.ClinicId == clinicId);

var grouped = 
   from p in filtered
   group p by p.TypeOfPatient into g
   select new
   {
      TypeOfPatient = g.Key,
      UploadedDate = g.Max(x.UploadedDate)
   };

var result = 
   from p in filtered
   join g in grouped on new { p.TypeOfPatient, p.UploadedDate } 
                 equals new { g.TypeOfPatient, g.UploadedDate }
   select p;
   
var result =  from p in db.patientsOfClinic 
    group p by p.TypeOfPatient into grp 
    select grp.OrderByDescending(o => o.UploadedDate).FirstOrDefault();

在这种情况下,您可以将 lambda 表达式用于 return 匿名对象,该对象为您提供专利类型列表,其中最大上传日期为真。

测试:

public class PatientsOfClinic
{
    public int Id { get; set; }
    public int ClinicId { get; set; }
    public string TypeOfPatient { get; set; }
    public DateTime UploadedDate { get; set; }
}


     var listOfPatents = new List<PatientsOfClinic>
           {
               new PatientsOfClinic
               {
                   Id =1 ,  
                   ClinicId=1,
                   TypeOfPatient = "child",
                   UploadedDate = DateTime.Today
               },
               new PatientsOfClinic
               {
                   Id =1 ,
                   ClinicId=1,
                   TypeOfPatient = "teenager",
                   UploadedDate = DateTime.Today.AddDays(1)
               }
            };
            var clinicId = 1;
                //listOfPatents
    //        .Where(c => c.ClinicId == clinicId)
    //        .GroupBy(x => x.TypeOfPatient)
    //        .Select(g => new
    //        {
    //            TypeOfPatient = g.Key,
    //            Patient = g.OrderByDescending(x => x.UploadedDate)
    //                             .FirstOrDefault()
    //        });

    listOfPatents
        .Where(c => c.ClinicId == clinicId)
        .GroupBy(x =>  x.TypeOfPatient)
        .SelectMany(g => g.Where(u=>u.UploadedDate == g.Max(m =>m.UploadedDate)))
}

您可以做的是:

首先,按上传日期对患者进行排序。

然后按类型分组。您将得到 4 个按日期排序的组。

从每组中取出第一个也是最新的患者。

这将产生一个包含 4 名患者的列表,每组各一名,具有最新的上传日期。

var patients = db.patientsOfClinic.OrderByDescending(patient => patient.UploadDate)
                                  .GroupBy(patient => patient.TypeOfPatient)
                                  .Select(g => g.FirstOrDefault());

The issue to get from list of patients only four patients, one patient of each type...

当有人说:我需要一个 属性 的物品时,你需要做的第一件事是,你是否应该想到 Queryable.GroupBy[=15 的重载之一=]

使用这种方法,您可以将具有某些共同价值的患者分组。在您的情况下,您将 属性 TypeOfPatient.

具有相同值的患者分组

结果是您得到一组 TypeOfPatient 值等于 Child 的患者,以及一组 TypeOfPatient 值等于 Adult 的患者,等等。

但您不只是想要一组患者,您想要从每个组中 select 一项。

... of each type and has the latest date of the last doctor's visit.

为此,您使用参数 resultSelector。此参数是一个具有两个输入值的方法:公共项目,在您的情况下为 TypeOfPatient,以及组中的所有患者。输出是一个对象。在您的情况下:您希望输出具有最新医生访问数据的组中的患者。

IQueryable<Patient> patients = ...
var result = patients.GroupBy(patient => patient.TypeOfPatient,

    // parameter resultSelector: take each found TypeOfPatient,
    // with all Patients that have this value for TypeOfPatient,
    // to make one new:
    (typeOfPatient, patientsOfThisType) =>

        // order all patients in this group by descending value for UploadedDate
        // and take the first
        patientsWithOfType.OrderByDescending(patient => patient.UploadedDate)
                          .FirstOrDefault());

您可以确定不会有任何空组。所以总会有第一个的。