DefaultIfEmpty()不处理空集合

时间:2019-07-18 08:51:22

标签: c# linq asp.net-core ef-core-2.2 sql-to-linq-conversion

我一直试图离开桌子,他们处于一对多关系。

我已经编写了一个SQL查询,并尝试将其转换为ASP.NET Core应用程序的LINQ。

我的sql查询如下:

    SELECT ap.SystemId, 
           ap.AccessRequiredToId, 
           cb.AccessAreaManagementId, 
           ap.EquipmentTagId, 
           COUNT(ap.Name) [Count] 
      FROM ApplicationForms ap LEFT JOIN AccessAreaCheckBoxes cb 
        ON n ap.RecordId = cb.RecordId
     WHERE EndDate IS NULL AND (Checked IS NULL OR Checked = 1)
  GROUP BY ap.SystemId, ap.AccessRequiredToId, cb.AccessAreaManagementId, ap.EquipmentTagId

SQL Result

我的LINQ如下:

var active = _context.ApplicationForms
                .Where(w => w.EndDate == null)
                .GroupJoin(_context.AccessAreaCheckBoxes
                .Where(w => (w.AccessAreaManagement == null || w.Checked == true)),
                x => x.RecordId,
                y => y.RecordId,
                (x, y) => new { ApplicationForms = x, AccessAreaCheckBoxes = y })
                .SelectMany(x => x.AccessAreaCheckBoxes.DefaultIfEmpty(),
                (x, y) => new { x.ApplicationForms, AccessAreaCheckBoxes = y })
                .GroupBy(g => new { g.ApplicationForms.System, g.ApplicationForms.AccessRequiredTo, g.AccessAreaCheckBoxes.AccessAreaManagement, g.ApplicationForms.EquipmentTag })
                .Select(s => new RecordViewModel
                {
                    System = s.Key.System.Name,
                    AccessRequiredTo = s.Key.AccessRequiredTo.Name,
                    AccessArea = s.Key.AccessAreaManagement.Name,
                    EquipmentTag = s.Key.EquipmentTag.Name,
                    Count = s.Count()
                }).ToList();

一切正常,除了它不显示带有NULL值的行。 我是否错过了LINQ中的某些内容? 任何帮助将不胜感激!

1 个答案:

答案 0 :(得分:0)

这是我最后要做的,请在此处发布以供参考。

    var active = (from ap in _context.ApplicationForms
                  join cb in _context.AccessAreaCheckBoxes
                  on ap.RecordId equals cb.RecordId into j1
                  from j2 in j1.DefaultIfEmpty()
                  where ap.EndDate == null
                  && (j2.AccessAreaManagement == null || j2.Checked == true)
                  group new { ap.System, ap.AccessRequiredTo, j2.AccessAreaManagement, ap.EquipmentTag } 
                  by new { System = ap.System.Name, Building = ap.AccessRequiredTo.Name, AccessArea = j2.AccessAreaManagement.Name, Equipment = ap.EquipmentTag.Name } into grp
                  select new RecordViewModel
                  {
                      System = grp.Key.System,
                      AccessRequiredTo = grp.Key.Building,
                      AccessArea = grp.Key.AccessArea,
                      EquipmentTag = grp.Key.Equipment,
                      Count = grp.Count()
                  }).ToList();