简体   繁体   English

C# 实体框架 OrderBy Children's Children's with a where 子句

[英]C# Entity Framework OrderBy Children's Children's with a where clause

I have a pretty complicated linq statement that gets a list of people (using Entity Framework) and I want to add an OrderBy clause to the end, depending on which column the user has clicked on for sorting.我有一个非常复杂的 linq 语句,它获取人员列表(使用实体框架),我想在末尾添加一个OrderBy子句,具体取决于用户单击哪个列进行排序。 I DON'T want to get all the people and then sort as there are potentially alot of people and we also do paging, so getting the data and then sorting/paging is not an option.我不想让所有人都进行排序,因为可能有很多人,而且我们也进行分页,所以获取数据然后排序/分页不是一种选择。 It must therefore be done using LINQ to EF.因此必须使用 LINQ 到 EF 来完成。

I have managed to get the search criteria that filters based on the status of the user's current vaccination status, but I am unable to "convert" that to an OrderBy statement我已经设法获得根据用户当前疫苗接种状态进行过滤的搜索条件,但我无法将其“转换”为OrderBy语句

The data I am getting relates to COVID vaccinations and whether the person's vaccination status is Full, Partial, Not Disclosed or None.我获得的数据与 COVID 疫苗接种有关,以及该人的疫苗接种状态是完全、部分、未披露还是无。

The Entity Framework LINQ statement with the Where clause looks like this and It is an IQueryable<Person> , not a List<Person> :带有Where子句的实体框架 LINQ 语句如下所示,它是IQueryable<Person> ,而不是List<Person>

people.Where(p => p.Encounters.Where(e =>
          e.EncounterItems.Any(ei => ei.PersonAssessments.Any(pa =>
          pa.Assessment.Questions.Any(q => q.questioncode.Equals("qIDateF", StringComparison.InvariantCultureIgnoreCase) || q.questioncode.Equals("qIDateP", StringComparison.InvariantCultureIgnoreCase)))))
          .OrderByDescending(e => e.servicedt ?? e.planneddt).FirstOrDefault()
          .EncounterItems.Where(ei =>
          ei.PersonAssessments.Any(pa => pa.Answers.Any(a => a.adate.HasValue && DbFunctions.AddMonths(a.adate, procedureCycleDays) < DateTime.Today &&
          (a.Question.questioncode.Equals("qIDateF", StringComparison.InvariantCultureIgnoreCase) || (a.Question.questioncode.Equals("qIDateP", StringComparison.InvariantCultureIgnoreCase)
          && (!pa.Answers.Any(aa => aa.adate.HasValue && aa.Question.questioncode.Equals("qIDateF", StringComparison.InvariantCultureIgnoreCase)))
          ))))).FirstOrDefault()
          != null)

From the above it will filter the people where their vaccination status is "Overdue".从上面它将过滤他们的疫苗接种状态为“过期”的人。 ie they have done either Partial or Full Vaccination but the cycle for this vaccination has been exceeded.即他们已经进行了部分或全部疫苗接种,但已超过此疫苗接种的周期。 There are 2 questions with questioncode's "qIDateP" (partial) and "qIDateF" (full).问题代码的“qIDateP”(部分)和“qIDateF”(完整)有 2 个问题。

I know the below OrderBy is completly wrong, but I want to do something like this so that all the people with overdue vaccination status's are at the top.我知道下面的OrderBy是完全错误的,但我想做这样的事情,以便所有疫苗接种过期的人都排在首位。 I will then add several other OrderBy clauses such as "Current" using the same clause, just chainging the date expression eg DbFunctions.AddMonths(a.adate, procedureCycleDays) >= DateTime.Today然后,我将使用相同的子句添加其他几个OrderBy子句,例如“Current”,只是链接日期表达式,例如DbFunctions.AddMonths(a.adate, procedureCycleDays) >= DateTime.Today

people.OrderBy(p => p.Encounters.Where(e =>
       e.EncounterItems.Any(ei => ei.PersonAssessments.Any(pa =>
       pa.Assessment.Questions.Any(q => q.questioncode.Equals("qIDateF", StringComparison.InvariantCultureIgnoreCase) || q.questioncode.Equals("qIDateP", StringComparison.InvariantCultureIgnoreCase)))))
       .OrderByDescending(e => e.servicedt ?? e.planneddt).FirstOrDefault()
       .EncounterItems.Where(ei =>
       ei.PersonAssessments.Any(pa => pa.Answers.Any(a => a.adate.HasValue && DbFunctions.AddMonths(a.adate, procedureCycleDays) < DateTime.Today &&
       (a.Question.questioncode.Equals("qIDateF", StringComparison.InvariantCultureIgnoreCase) || (a.Question.questioncode.Equals("qIDateP", StringComparison.InvariantCultureIgnoreCase)
       && (!pa.Answers.Any(aa => aa.adate.HasValue && aa.Question.questioncode.Equals("qIDateF", StringComparison.InvariantCultureIgnoreCase)))
       ))))).FirstOrDefault()
       != null)

The Relationships for the EF Models is as follows: EF 模型的关系如下:

Person => Encounter => EncounterItem => PersonAssessment => Answer

A person can answer multiple Assessments over their life and can change their mind as to whether they want to disclose their vaccination status or not.一个人可以在一生中回答多项评估,并且可以改变他们是否要披露其疫苗接种状态的想法。

NOTE: We are using the latest Entity Framework 6.4.4注意:我们使用的是最新的 Entity Framework 6.4.4

I hope someone can help me with the OrderBy clause as Im at a complete loss as to how to achieve this.我希望有人可以帮助我解决 OrderBy 条款,因为我完全不知道如何实现这一点。

Well as far as I can tell you want to use orderBy and then simply fetch the first element, while you could simply fetch the first element with the same predicate dropping O(nlogn) complexity好吧,据我所知,您想使用 orderBy 然后简单地获取第一个元素,而您可以使用相同的谓词简单地获取第一个元素,从而降低 O(nlogn) 复杂度

var result = people.Where(
    p => p.Encounters.Where(
        e => e.EncounterItems.Any(
            ei => ei.PersonAssessments.Any(
                pa => pa.Assessment.Questions.Any(
                    q => q.questioncode.Equals("qIDateF", StringComparison.InvariantCultureIgnoreCase) 
                      || q.questioncode.Equals("qIDateP", StringComparison.InvariantCultureIgnoreCase)))))
      .FirstOrDefault(e => e.servicedt ?? e.planneddt) // you have 1 Encounters item
      .EncounterItems.FirstOrDefault(
        ei => ei.PersonAssessments.Any(
            pa => pa.Answers.Any(
                a => a.adate.HasValue 
                    && DbFunctions.AddMonths(a.adate, procedureCycleDays) < DateTime.Today 
                      && (a.Question.questioncode.Equals("qIDateF", StringComparison.InvariantCultureIgnoreCase) 
                        || (a.Question.questioncode.Equals("qIDateP", StringComparison.InvariantCultureIgnoreCase)
                          && (!pa.Answers.Any(aa => aa.adate.HasValue && aa.Question.questioncode.Equals("qIDateF", StringComparison.InvariantCultureIgnoreCase)))))))));

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM