【问题标题】:DefaultIfEmpty() does not handle empty collectionsDefaultIfEmpty() 不处理空集合
【发布时间】:2019-07-18 08:51:22
【问题描述】:

我一直在尝试左加入表,它们是一对多的关系。

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

我的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 中的某些内容? 任何帮助将不胜感激!

【问题讨论】:

  • DefaultIfEmpty() 返回指定序列的元素,如果序列为空,则返回单例集合中的指定值。
  • 您使用的是哪个版本的 EF?核心还是6?请编辑问题并在此处指定。我的两分钱:如果使用 EF Core,我非常有信心查询不会被翻译成 SQL 并将在内存中进行评估。您可以在控制台中检查它,它应该会产生警告。在这种情况下,我将只使用您的 SQL 查询并完成它。查询很容易理解,这个 linq .. 不是那么多。您可以查看查询类型:docs.microsoft.com/en-us/ef/core/modeling/query-types
  • @jpgrassi 这是 EF Core。是的 linq 很不错,但是我已经找到了我的解决方案并将很快发布,无论如何感谢您的建议。

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


【解决方案1】:

这是我最后做的,发在这里供大家参考。

    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();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-09-19
    • 2021-02-25
    • 2013-07-23
    • 1970-01-01
    • 1970-01-01
    • 2010-12-14
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多