2011-07-07 13 views
9

Tengo problemas. No puedo entender las respuestas existentes a esto en Stack Overflow y soy demasiado nuevo para LINQ to SQL para poder desenmascararme.Convertir simple SQL group-by en LINQ to SQL

Ver este SQL:

select p.Name as ProductName, SUM(o.NumberOf) as TotalOrdered from [Order] o 
    join [Product] p on o.ProductId = p.Id 
    group by p.Name 

Devuelve una bonita mesa de 2 columnas con los nombres de productos a la izquierda y el número total de ese producto que se han ordenado (en todos los órdenes) en la columna de la derecha. ¿Cómo puedo duplicar esto en LINQ to SQL?

Aquí es lo que tengo hasta ahora:

var ctx = new DataClasses1DataContext(); 
var totalProducts = (from o in ctx.Orders 
        join p in ctx.Products on o.ProductId equals p.Id 
        select new { p.Name, o.NumberOf }) 
    .GroupBy(t => t.Name) 
    .Select(g => g.Key, ...); 

lo que sucede en el ...?

Respuesta

25

A mi me parece como si quieres:

.Select(g => new { ProductName = g.Key, TotalOrdered = g.Sum(x => x.NumberOf) }) 

usted puede hacer su consulta completa como sea una sola expresión de consulta o sin usar expresiones de consulta:

var totalProducts = ctx.Orders 
         .Join(ctx.Products, o => o.ProductId, p => p.Id, 
          (o, p) => new { p.Name, o.NumberOf }) 
         .GroupBy(t => t.Name, 
           pair => pair.Name, // Key selector 
           pair => pair.NumberOf, // Element selector 
           (key, numbers) => new { 
            ProductName = key, 
            TotalOrdered = numbers.Sum()) 
           }); 

O:

var totalProdcuts = from o in ctx.Orders 
        join p in ctx.Products on o.ProductId equals p.Id 
        group o.NumberOf by p.Name into g 
        select new { ProductName = g.Key, TotalOrdered = g.Sum() }; 
+0

Esto es correcto. Acabo de comprobar. Gracias por ayudarme en mi momento de muerte cerebral. – Lisa

+1

@Lisa: Bien - editará más ... –

+0

En respuesta a su actualización, ya estoy agrupando por nombre. – Lisa

2
TotalOrdered = g.Sum(o => o.NumberOf) 

hacer uso de más arriba para que .... declaración podría ser

select new { ProductName= g.Key, TotalOrdered = g.Sum(o => o.NumberOf) }; 

var query = from o in ctx.Orders 
      join p in ctx.Products on 
      o.ProductId equals p.Id 
      group o by new { p.Name, o.NumberOf } into g 
      select new { ProductName= g.Key, TotalOrdered = g.Sum(o => o.NumberOf) }; 
+0

Entiendo cómo obtener la suma. Lo que me confundía era cómo convertirlo en una proyección. – Lisa

+0

@Lisa - inténtalo ahora –

+0

Sí, esto también funciona a la perfección. Creo que era lo que estaba buscando al principio. Es mucho más elegante que la combinación de extensiones LINQ-a-SQL y Linq. – Lisa

0

Sólo pegar esto aquí por si es útil saber cómo esto podría lograrse a través del método GroupJoin:

var totalProducts = ctx.Products.GroupJoin(ctx.Orders, 
    outerKeySelProduct => outerKeySelProduct.Id, 
    innerKeySelOrder => innerKeySelOrder.ProductId, 
    (outerKeySelProduct, innerKeySelOrder) => new 
    { 
     ProductName = outerKeySelProduct.Name, 
     TotalOrdered = innerKeySelOrder.Select(n => n.NumberOf).Sum() 
    }); 

feliz para que pueda ser editado si se puede mejorar.