it-swarm.com.de

LINQ - Linker Join, Gruppieren nach und Zählen

Nehmen wir an, ich habe diese SQL:

SELECT p.ParentId, COUNT(c.ChildId)
FROM ParentTable p
  LEFT OUTER JOIN ChildTable c ON p.ParentId = c.ChildParentId
GROUP BY p.ParentId

Wie kann ich das in LINQ to SQL übersetzen? Ich bin bei der COUNT (c.ChildId) hängen geblieben, die generierte SQL scheint immer COUNT (*) auszugeben. Folgendes habe ich bisher bekommen:

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() }

Vielen Dank!

165
pbz
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) }
185
Mehrdad Afshari

Erwägen Sie die Verwendung einer Unterabfrage:

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 } ;

Wenn die Abfragetypen durch eine Zuordnung verbunden sind, vereinfacht dies Folgendes:

from p in context.ParentTable 
let cCount = p.Children.Count()
select new { ParentId = p.Key, Count = cCount } ;
55
Amy B

SPÄTE ANTWORT:

Sie sollten den linken Join nicht benötigen, wenn Sie nur Count () ausführen. Beachten Sie, dass join...into Tatsächlich in GroupJoin übersetzt wird, was Gruppierungen wie new{parent,IEnumerable<child>} Zurückgibt, sodass Sie nur Count() für die Gruppe aufrufen müssen:

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() }

In der Syntax der Erweiterungsmethode entspricht ein join intoGroupJoin (während ein join ohne ein intoJoin ist):

context.ParentTable
    .GroupJoin(
                   inner: context.ChildTable
        outerKeySelector: parent => parent.ParentId,
        innerKeySelector: child => child.ParentId,
          resultSelector: (parent, children) => new { parent.Id, Count = children.Count() }
    );
33
Eren Ersönmez
 (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) })
7
雪域飞貂

Während die Idee hinter der LINQ-Syntax darin besteht, die SQL-Syntax zu emulieren, sollten Sie nicht immer daran denken, Ihren SQL-Code direkt in LINQ zu übersetzen. In diesem speziellen Fall brauchen wir Gruppe in nicht zu tun, da Verbindung in eine Gruppe ist, die sich selbst verbindet.

Hier ist meine Lösung:

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() }

Anders als bei der meistgewählten Lösung hier ist es nicht erforderlich, j1, j2 und null einzuchecken Count (t => t.ChildId! = Null)

7
Mosh