首頁 >資料庫 >mysql教程 >如何將具有多個聯結、計數和左聯接的複雜 SQL 查詢轉換為 LINQ?

如何將具有多個聯結、計數和左聯接的複雜 SQL 查詢轉換為 LINQ?

Barbara Streisand
Barbara Streisand原創
2025-01-25 04:18:08367瀏覽

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