首页 > 数据库 > mysql教程 > 如何将具有多个联接、计数和左联接的复杂 SQL 查询转换为 LINQ?

如何将具有多个联接、计数和左联接的复杂 SQL 查询转换为 LINQ?

Barbara Streisand
发布: 2025-01-25 04:18:08
原创
366 人浏览过

How to Translate a Complex SQL Query with Multiple Joins, Counts, and a Left Join into LINQ?

将包含多个连接、计数和左连接的SQL查询转换为LINQ

您的SQL查询使用了多个连接、左连接和聚合函数来从多个表中检索数据。要将此查询转换为LINQ,请按照以下步骤操作:

  • 转换子查询: 将子查询提取到单独的变量中,除非它们引用子查询之外的列。
  • 使用表别名: 使用表别名作为范围变量,列别名作为匿名类型字段名。
  • 处理连接: 如果使用EF/EF Core,则将JOIN子句转换为导航属性。否则,使用匿名对象或交叉连接以及WHERE和LEFT JOIN模拟。
  • 聚合函数: 使用LINQ聚合函数来代替SQL聚合函数,例如COUNT。
  • Distinct(): 使用Distinct()方法转换DISTINCT。
  • LEFT JOIN: 使用into、from和DefaultIfEmpty()模拟LEFT JOIN。
  • 匿名类型: 使用匿名类型来组合多个列。

原始SQL查询:

<code class="language-sql">SELECT DISTINCT c.Id, 
       c.Title, 
       COUNT(v.Id) AS 'Nb_V2',
       COUNT(DISTINCT v.IdUser) AS 'Nb_V1',
       r.cnt AS 'Nb_R'
FROM TABLE_C c
JOIN TABLE_V v on c.Id = v.Id
LEFT JOIN ( 
    SELECT Id, COUNT(*)  AS cnt 
    FROM TABLE_R 
    GROUP BY Id
) r ON c.Id = r.Id
WHERE c.IdUser = '1234'
GROUP BY c.Id, c.Title, r.cnt</code>
登录后复制

LINQ查询表达式转换(改进版):

<code class="language-csharp">var qResult = (from c in dbContext.TABLE_C
              join v in dbContext.TABLE_V on c.Id equals v.Id
              from r in dbContext.TABLE_R.Where(r => r.Id == c.Id).DefaultIfEmpty()
              where c.IdUser == "1234"
              group new { c, v, r } by new { c.Id, c.Title } into grouped
              select new
              {
                  IdC = grouped.Key.Id,
                  Title = grouped.Key.Title,
                  Nb_V2 = grouped.Count(g => g.v.Id != null),
                  Nb_V1 = grouped.Select(g => g.v.IdUser).Distinct().Count(),
                  Nb_R = grouped.Sum(g => (int?)g.r.cnt ?? 0) // 处理r.cnt可能为null的情况
              }).Distinct();</code>
登录后复制

Lambda表达式转换:

<code class="language-csharp">var ansq = dbContext.TABLE_C
    .Where(c => c.IdUser == "1234")
    .Join(dbContext.TABLE_V, c => c.Id, v => v.Id, (c, v) => new { c, v })
    .GroupJoin(dbContext.TABLE_R, cv => cv.c.Id, r => r.Id, (cv, r) => new { cv, r })
    .SelectMany(x => x.r.DefaultIfEmpty(), (x, r) => new { x.cv.c, x.cv.v, r })
    .GroupBy(x => new { x.c.Id, x.c.Title, cnt = (int?)x.r?.cnt })
    .Select(g => new
    {
        g.Key.Title,
        Nb_V2 = g.Count(x => x.v.Id != null),
        Nb_V1 = g.Select(x => x.v.IdUser).Distinct().Count(),
        Nb_R = g.Key.cnt
    })
    .Distinct();
</code>
登录后复制

这个改进后的LINQ查询更简洁高效地处理了COUNT函数和LEFT JOIN,并避免了原代码中的一些潜在问题,例如t.Id > 0 的奇怪判断以及r.cnt可能为null的情况。 它更准确地反映了原始SQL查询的逻辑。 请注意,你需要根据你的数据库上下文和实体名称调整dbContext.TABLE_CdbContext.TABLE_VdbContext.TABLE_R

以上是如何将具有多个联接、计数和左联接的复杂 SQL 查询转换为 LINQ?的详细内容。更多信息请关注PHP中文网其他相关文章!

本站声明
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
作者最新文章
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板