简体   繁体   English

如何在Linq中按具有复杂类型的多列分组

[英]How to group by multiple columns with complex types in Linq

I'm trying to preform a group by to get all of the students, by college, grouped by status. 我正在尝试组建一个小组,以便按大学将所有学生按状态分组。 The problem is the database I'm working with has hundreds of fields in the StudentInfo table, which is why I think this is failing. 问题是我正在使用的数据库在StudentInfo表中有数百个字段,这就是为什么我认为这失败了。

I'm basically trying to get counts for the students by their statuses, and grouped by the college they are from. 我基本上是在尝试根据学生的身份来获取学生的人数,并按照他们来自的大学来进行分组。

When I execute this query, I get the following exception. 执行此查询时,出现以下异常。

The key selector type for the call to the 'GroupBy' method is not comparable in the underlying store provider. 在基础商店提供程序中,用于调用“ GroupBy”方法的键选择器类型不可比。

Now I believe this is because there are way too many fields on the StudentInfo table, but I can't do anything about that in this case. 现在,我相信这是因为StudentInfo表上的字段太多了,但是在这种情况下,我无法执行任何操作。 There has to be a way to do what I want. 必须有一种方法可以做我想要的。

I need the following fields returned, all of which are counts, except College. 我需要返回以下字段,所有字段都是计数,大学除外。

College | 学院| Accepts | 接受| Webapps | Webapps | Ays | Ays | Total

Can someone please point me in the right direction. 有人能指出我正确的方向吗?

Here is my model 这是我的模特

public class EnrollmentCountsBySchool
{
    // selected terms
    public int[] SelectedTerms { get; set; }
    // list of terms
    public IEnumerable<SelectListItem> Terms { get; set; }

    // selected programs
    public int[] SelectedPrograms { get; set; }
    // list of programs
    public IEnumerable<SelectListItem> Programs { get; set; }

    // selected statuses
    public string[] SelectedStatuses { get; set; }
    // list of statuses
    public IEnumerable<SelectListItem> Statuses { get; set; }

    // list of results
    public List<EnrollmentCountsBySchoolResult> Results { get; set; }

My Query (way to long, I know.) 我的查询(很长一段时间,我知道。)

 var results =
            (from student in db.StudentInfo
             join college in db.Colleges on student.College.Id equals college.Id
             where model.SelectedTerms.Contains(student.TermOfInterestId.Value) &&
                   model.SelectedPrograms.Contains(student.ProgramId.Value) &&
                   model.SelectedStatuses.Contains(student.Status)

             group student by new
             {
                 College = college.Name,
                 Accepts = (
                         from s in db.StudentInfo
                         join c in db.Colleges on student.College.Id equals college.Id
                         where model.SelectedTerms.Contains(student.TermOfInterestId.Value) &&
                               model.SelectedPrograms.Contains(student.ProgramId.Value) &&
                               model.SelectedStatuses.Contains(student.Status) &&
                               student.Status.ToLower().Contains("accepted") ||
                               student.Status.ToLower().Contains("applicant")
                         group s by new
                         {
                             College = c.Name,
                         } into accepts
                         select new
                         {
                             accepts.Key.College,
                             Count = accepts.Count()
                         }
                 ),
                 Webapps =
                 (
                         from s in db.StudentInfo
                         join c in db.Colleges on student.College.Id equals college.Id
                         where model.SelectedTerms.Contains(student.TermOfInterestId.Value) &&
                               model.SelectedPrograms.Contains(student.ProgramId.Value) &&
                               model.SelectedStatuses.Contains(student.Status) &&
                               student.Status.ToLower().Contains("webapp")
                         group s by new
                         {
                             College = c.Name,
                         } into webapps
                         select new
                         {
                             webapps.Key.College,
                             Count = webapps.Count()
                         }
                 ),
                 Ays = (
                         from s in db.StudentInfo
                         join c in db.Colleges on student.College.Id equals college.Id
                         where model.SelectedTerms.Contains(student.TermOfInterestId.Value) &&
                               model.SelectedPrograms.Contains(student.ProgramId.Value) &&
                               model.SelectedStatuses.Contains(student.Status) &&
                               !student.Status.ToLower().Contains("accepted") &&
                               !student.Status.ToLower().Contains("applicant") &&
                               !student.Status.ToLower().Contains("webapp")
                         group s by new
                         {
                             College = c.Name,
                         } into ays
                         select new
                         {
                             ays.Key.College,
                             Count = ays.Count()
                         }
                 ),
                 Total = (
                         from s in db.StudentInfo
                         join c in db.Colleges on student.College.Id equals college.Id
                         where model.SelectedTerms.Contains(student.TermOfInterestId.Value) &&
                               model.SelectedPrograms.Contains(student.ProgramId.Value) &&
                               model.SelectedStatuses.Contains(student.Status)
                         group s by new
                         {
                             College = c.Name,
                         } into totals
                         select new
                         {
                             totals.Key.College,
                             Count = totals.Count()
                         }
                 )

             }
                 into grouping
                 select new EnrollmentCountsBySchoolResult
                 {
                     College = grouping.Key.College,
                     Accepts = grouping.Key.Accepts.Count(),
                     Webapps = grouping.Key.Webapps.Count(),
                     Ays = grouping.Key.Ays.Count(),
                     Total = grouping.Key.Total.Count()
                 }).ToList();

I ended up re-writing the query to search by colleges and join students, then do the grouping and I got the results I was looking for. 最后,我重新编写了查询,以供大学搜索并加入学生,然后进行分组,然后得到了所需的结果。

       var results =
            from college in db.Colleges
            join student in db.StudentInfo on college.Id equals student.UniversityId
            where model.SelectedTerms.Contains(student.TermOfInterestId.Value) &&
                  model.SelectedPrograms.Contains(student.ProgramId.Value) &&
                  model.SelectedStatuses.Contains(student.Status)
            group college by new
            {
                College = college.Name,
                Accepts = (
                 from c1 in db.Colleges
                 join s1 in db.StudentInfo on c1.Id equals s1.UniversityId
                 where model.SelectedTerms.Contains(s1.TermOfInterestId.Value) &&
                       model.SelectedPrograms.Contains(s1.ProgramId.Value) &&
                       model.SelectedStatuses.Contains(s1.Status) &&
                       s1.UniversityId == college.Id &&
                       s1.Status.ToLower().Contains("accepted") || s1.Status.ToLower().Contains("applicant")
                 select c1
                ).Count(),
                Webapps = (
                    from c2 in db.Colleges
                    join s2 in db.StudentInfo on c2.Id equals s2.UniversityId
                    where model.SelectedTerms.Contains(s2.TermOfInterestId.Value) &&
                          model.SelectedPrograms.Contains(s2.ProgramId.Value) &&
                          model.SelectedStatuses.Contains(s2.Status) &&
                          s2.UniversityId == college.Id &&
                          s2.Status.ToLower().Contains("webapp")
                    select c2
                ).Count(),
                Ays = (
                    from c3 in db.Colleges
                    join s3 in db.StudentInfo on c3.Id equals s3.UniversityId
                    where model.SelectedTerms.Contains(s3.TermOfInterestId.Value) &&
                          model.SelectedPrograms.Contains(s3.ProgramId.Value) &&
                          model.SelectedStatuses.Contains(s3.Status) &&
                          s3.UniversityId == college.Id &&
                          !s3.Status.ToLower().Contains("accepted") && !s3.Status.ToLower().Contains("applicant") &&
                          !s3.Status.ToLower().Contains("webapp")
                    select c3
                ).Count()
            }
                into grouping
                select new EnrollmentCountsBySchoolResult
                {
                    College = grouping.Key.College,
                    Accepts = grouping.Key.Accepts,
                    Webapps = grouping.Key.Webapps,
                    Ays = grouping.Key.Ays,
                    Total = grouping.Count()
                };

        model.Results = results.OrderByDescending(o => o.Total).ToList();

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

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