Maison > base de données > tutoriel mysql > Comment traduire une requête SQL complexe avec plusieurs jointures, comptes et une jointure de gauche dans LINQ?

Comment traduire une requête SQL complexe avec plusieurs jointures, comptes et une jointure de gauche dans LINQ?

Barbara Streisand
Libérer: 2025-01-25 04:18:08
original
322 Les gens l'ont consulté

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

Convertir les requêtes SQL contenant plusieurs jointures, comptes et jointures gauches en LINQ

Votre requête SQL utilise plusieurs jointures, jointures gauches et fonctions d'agrégation pour récupérer les données de plusieurs tables. Pour convertir cette requête en LINQ, suivez ces étapes :

  • Convertir les sous-requêtes : Extraire les sous-requêtes dans des variables distinctes, sauf si elles font référence à des colonnes en dehors de la sous-requête.
  • Utiliser des alias de table : Utilisez des alias de table comme variables de portée et des alias de colonnes comme noms de champs de type anonyme.
  • Gestion des jointures : Si vous utilisez EF/EF Core, convertissez la clause JOIN en propriété de navigation. Sinon, utilisez des objets anonymes ou des jointures croisées et des simulations WHERE et LEFT JOIN.
  • Fonctions d'agrégation : Utilisez les fonctions d'agrégation LINQ au lieu des fonctions d'agrégation SQL, telles que COUNT.
  • Distinct() : Utilisez la méthode Distinct() pour convertir DISTINCT.
  • LEFT JOIN : Utilisez into, from et DefaultIfEmpty() pour simuler LEFT JOIN.
  • Types anonymes : Utilisez des types anonymes pour combiner plusieurs colonnes.

Requête SQL originale :

<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>
Copier après la connexion

Conversion d'expression de requête LINQ (version améliorée) :

<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>
Copier après la connexion

Conversion d'expressions 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>
Copier après la connexion

Cette requête LINQ améliorée gère la fonction COUNT et LEFT JOIN de manière plus concise et efficace, et évite certains problèmes potentiels dans le code d'origine, tels que le jugement étrange de t.Id > 0 et la possibilité que r.cnt soit nul. Cela reflète plus précisément la logique de la requête SQL d'origine. Notez que vous devrez ajuster dbContext.TABLE_C, dbContext.TABLE_V et dbContext.TABLE_R en fonction du contexte de votre base de données et du nom de votre entité.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal