Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Convert simple SQL group-by into LINQ to SQL

I'm having trouble. I can't understand existing answers to this on Stack Overflow and am too new to LINQ to SQL to be able to nut it out myself.

See this 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

Returns a nice 2-column table with product names on the left and the total number that product which have been ordered (across all orders) in the right column. How can I duplicate this in LINQ to SQL?

Here is what I've got so far:

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, ... );

What goes at the ... ?

like image 437
Lisa Avatar asked Jul 07 '11 05:07

Lisa


People also ask

How can we do a GroupBy using LINQ query?

Group by single property example The following example shows how to group source elements by using a single property of the element as the group key. In this case the key is a string , the student's last name. It is also possible to use a substring for the key; see the next example.

Is LINQ to SQL obsolete?

"As long as LINQ to SQL lives under Entity Framework, it's dead.

How LINQ queries converted into SQL queries?

LINQ to SQL translates the queries you write into equivalent SQL queries and sends them to the server for processing. More specifically, your application uses the LINQ to SQL API to request query execution. The LINQ to SQL provider then transforms the query into SQL text and delegates execution to the ADO provider.

Why we use LINQ instead of SQL?

SQL isn't broken, so why fix it? Why do we need another querying language? The popular answer is that LINQ is INtegrated with C# (or VB), thereby eliminating the impedance mismatch between programming languages and databases, as well as providing a single querying interface for a multitude of data sources.


3 Answers

It looks to me like you want:

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

You can do your whole query as either a single query expression or without using query expressions at all though:

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

Or:

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() };
like image 112
Jon Skeet Avatar answered Oct 21 '22 20:10

Jon Skeet


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

make use of above for .... than statement might be

   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) };
like image 20
Pranay Rana Avatar answered Oct 21 '22 18:10

Pranay Rana


Just pasting this here in case it is helpful to know how this could be achieved through GroupJoin method:

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

Happy for it to be edited if it can be improved.

like image 1
Lisa Avatar answered Oct 21 '22 19:10

Lisa