visual studio online net framework examples conexion asp c# .net linq linq-to-sql

c# - studio - linq to sql vs entity framework



LINQ-Unir, agrupar y contar (5)

Digamos que tengo este SQL:

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

¿Cómo puedo traducir esto a LINQ to SQL? Me quedé atrapado en el COUNT (c.ChildId), el SQL generado siempre parece dar como resultado COUNT (*). Esto es lo que obtuve hasta ahora:

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

¡Gracias!


Considera usar una subconsulta:

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 los tipos de consulta están conectados por una asociación, esto se simplifica a:

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


Si bien la idea detrás de la sintaxis LINQ es emular la sintaxis de SQL, no siempre se debe pensar en traducir directamente su código SQL a LINQ. En este caso particular, no es necesario agruparnos porque join es un join de grupo.

Aquí está mi solución:

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

A diferencia de la solución más votado aquí, no necesitamos j1 , j2 y comprobación nula en Count (t => t.ChildId! = Null)


RESPUESTA TARDÍA:

No deberías necesitar la combinación izquierda si todo lo que haces es Count (). Tenga en cuenta que join...into se traduce realmente a GroupJoin que devuelve agrupaciones como new{parent,IEnumerable<child>} por lo que solo necesita llamar a Count() en el grupo:

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

En la sintaxis del método de extensión, una join into es equivalente a la GroupJoin de GroupJoin (mientras que una join sin una into es 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) })


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