Maison >base de données >tutoriel mysql >Comment convertir une requête SQL complexe avec plusieurs jointures, comptes et jointures gauches en LINQ ?

Comment convertir une requête SQL complexe avec plusieurs jointures, comptes et jointures gauches en LINQ ?

Barbara Streisand
Barbara Streisandoriginal
2025-01-25 04:43:09717parcourir

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

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

Cet exemple montre comment convertir une requête SQL complexe contenant plusieurs jointures et agrégations en une requête LINQ équivalente. Cette requête récupère les données de trois tables (TABLE_C, TABLE_V et TABLE_R) et effectue une opération de comptage distincte sur des colonnes spécifiques.

Convertir SQL en compréhension des requêtes LINQ :

  1. Sous-requêtes de groupe : Convertissez les sous-requêtes en variables déclarées individuellement. Dans cet exemple, TABLE_R est regroupé à l'aide de types anonymes Id et Count.
  2. Clause de jointure : Utilisez des propriétés de navigation ou des objets anonymes pour rejoindre, et utilisez into et DefaultIfEmpty() pour simuler un LEFT JOIN.
  3. GroupBy : Regroupe les résultats sur plusieurs colonnes en utilisant un type anonyme. Utilisez Distinct() pour compter les résultats agrégés.
  4. Sélectionner : Sélectionnez les colonnes requises en créant un type anonyme avec les champs spécifiés.

Ce qui suit est le code LINQ écrit dans la syntaxe d'expression de requête :

<code class="language-csharp">var subrq = from r in Table_R
            group r by r.Id into rg
            select new { Id = rg.Key, cnt = rg.Count() };

var ansq = (from c in Table_C
            join v in Table_V on c.Id equals v.Id
            join r in subrq on c.Id equals r.Id into rj
            from r in rj.DefaultIfEmpty()
            where c.IdUser == "1234"
            group new { c, v, r } by new { c.Id, c.Title, r.cnt } into cvrg
            select new {
                cvrg.Key.Title,
                Nb_V2 = cvrg.Count(),
                Nb_V1 = cvrg.Select(cvr => cvr.v.IdUser).Distinct().Count(),
                Nb_R = (int?)cvrg.Key.cnt
            }).Distinct();</code>

Ce qui suit est le code LINQ équivalent écrit dans la syntaxe d'expression Lambda :

<code class="language-csharp">var subr2 = Table_R.GroupBy(r => r.Id).Select(rg => new { Id = rg.Key, cnt = rg.Count() });
var ans2 = Table_C.Where(c => c.IdUser == "1234")
                  .Join(Table_V, c => c.Id, v => v.Id, (c, v) => new { c, v })
                  .GroupJoin(subr2, cv => cv.c.Id, r => r.Id, (cv, rj) => new { cv.c, cv.v, rj })
                  .SelectMany(cvrj => cvrj.rj.DefaultIfEmpty(), (cvrj, r) => new { cvrj.c, cvrj.v, r })
                  .GroupBy(cvr => new { cvr.c.Id, cvr.c.Title, cvr.r?.cnt }) //处理r可能为null的情况
                  .Select(cvrg => new { 
                      cvrg.Key.Title, 
                      Nb_V2 = cvrg.Count(), 
                      Nb_V1 = cvrg.Select(cvr => cvr.v.IdUser).Distinct().Count(), 
                      Nb_R = (int?)cvrg.Key.cnt 
                  }).Distinct();</code>

Faites attention au traitement de cvr.r.cnt dans la version d'expression Lambda. L'opérateur conditionnel ?. null est ajouté pour gérer la situation où r peut être nul, évitant ainsi les exceptions NullReferenceException. Les deux méthodes accomplissent la même fonctionnalité, et la méthode que vous choisissez dépend de vos préférences personnelles.

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!

Déclaration:
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