Disons que j'ai ce SQL:
SELECT p.ParentId, COUNT(c.ChildId)
FROM ParentTable p
LEFT OUTER JOIN ChildTable c ON p.ParentId = c.ChildParentId
GROUP BY p.ParentId
Comment puis-je traduire cela en LINQ to SQL? Je me suis retrouvé coincé au COUNT (c.ChildId), le SQL généré semble toujours sortir COUNT (*). Voici ce que j'ai eu jusqu'à présent:
from p in context.ParentTable
join c in context.ChildTable on p.ParentId equals c.ChildParentId into j1
from j2 in j1.DefaultIfEmpty()
group j2 by p.ParentId into grouped
select new { ParentId = grouped.Key, Count = grouped.Count() }
Je vous remercie!
from p in context.ParentTable
join c in context.ChildTable on p.ParentId equals c.ChildParentId into j1
from j2 in j1.DefaultIfEmpty()
group j2 by p.ParentId into grouped
select new { ParentId = grouped.Key, Count = grouped.Count(t=>t.ChildId != null) }
Pensez à utiliser une sous-requête:
from p in context.ParentTable
let cCount =
(
from c in context.ChildTable
where p.ParentId == c.ChildParentId
select c
).Count()
select new { ParentId = p.Key, Count = cCount } ;
Si les types de requête sont connectés par une association, cela simplifie:
from p in context.ParentTable
let cCount = p.Children.Count()
select new { ParentId = p.Key, Count = cCount } ;
TARD REPONSE:
Vous ne devriez pas avoir besoin de la jointure gauche du tout si tout ce que vous faites est Count (). Notez que join...into
est en fait traduit en GroupJoin
qui renvoie des groupements tels que new{parent,IEnumerable<child>}
de sorte qu'il vous suffit d'appeler Count()
sur le groupe:
from p in context.ParentTable
join c in context.ChildTable on p.ParentId equals c.ChildParentId into g
select new { ParentId = p.Id, Count = g.Count() }
Dans la méthode d'extension, la syntaxe join into
équivaut à GroupJoin
(alors qu'une join
sans into
correspond à Join
):
context.ParentTable
.GroupJoin(
inner: context.ChildTable
outerKeySelector: parent => parent.ParentId,
innerKeySelector: child => child.ParentId,
resultSelector: (parent, children) => new { parent.Id, Count = children.Count() }
);
(from p in context.ParentTable
join c in context.ChildTable
on p.ParentId equals c.ChildParentId into j1
from j2 in j1.DefaultIfEmpty()
select new {
ParentId = p.ParentId,
ChildId = j2==null? 0 : 1
})
.GroupBy(o=>o.ParentId)
.Select(o=>new { ParentId = o.key, Count = o.Sum(p=>p.ChildId) })
Bien que la syntaxe LINQ repose sur l’émulation de la syntaxe SQL, vous ne devriez pas toujours penser à traduire directement votre code SQL en LINQ. Dans ce cas particulier, il n'est pas nécessaire de faire group into car join into est un groupe à joindre lui-même.
Voici ma solution:
from p in context.ParentTable
join c in context.ChildTable on p.ParentId equals c.ChildParentId into joined
select new { ParentId = p.ParentId, Count = joined.Count() }
Contrairement à la solution la plupart du temps votée ici, nous n’avons pas besoin de j1, j2 et de la vérification nulle dans Count (t => t.ChildId! = Null)