Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ Sum with GroupBy

Tags:

c#

linq

(Not sure if I even need GroupBy)

My (simplified) tables:

Products (ProductID, Name, Code)
Invoices (InvoiceID, Number, IsPaid)
Invoices_Products (InvoiceID, ProductID, Quantity, Price) - the many-to-many linking table

I need to show a list of Invoices_Products of paid Invoices grouped by the Product Code which sums (Quantity*Price).

The code that I first use to get a collection that I can bind to the UI:

IEnumerable<Invoices_Products> invoices_products = db.Invoices_Products
.Where(ip => ip.Invoice.IsPaid).DistinctBy(m => m.Product.Code);

I then iterate through this to bind it to the UI:

List<BindableInvoiceProduct> bindableInvoiceProducts = 
new List<BindableInvoiceProduct>();

foreach (var item in invoices_products)
{
    decimal salesValue = db.Invoices_Products.Where(ip => ip.Invoice.IsPaid 
    && ip.Product.Code == item.Product.Code).Sum(m => (m.Price * m.Quantity));

    bindableInvoiceProducts.Add(new BindableInvoiceProduct()
    {
        A = item.A,
        B = item.B,
        SalesValue = salesValue.ToString()
    });
}

(The DistinctBy method there is from morelinq)

Why does this not total correctly?

edit:

Some data:

Product - ProductID = 1, Name = 123, Code = A
Product - ProductID = 2, Name = 456, Code = A
Invoice - InvoiceID = 1, Number = INV123, IsPaid = True
Invoices_Products - InvoiceID = 1, ProductID = 1, Quantity = 10, Price = 100
Invoices_Products - InvoiceID = 1, ProductID = 2, Quantity = 10, Price = 200

Expected result:

Code = A, SalesValue = 3000

like image 853
notAnonymousAnymore Avatar asked Aug 08 '13 20:08

notAnonymousAnymore


People also ask

How do you sum in Linq?

In LINQ, you can find the sum of the given numeric elements by using the Sum() method. This method calculates the sum of the numeric value present in the given sequence. It does not support query syntax in C#, but it supports in VB.NET. It is available in both Enumerable and Queryable classes in C#.

How do you sum two columns in Linq?

Items select new { Sum(p. Total), Sum(p. Done)};

What is aggregate in Linq C#?

In LINQ, aggregation functions are those functions which are used to calculate a single value from the collection of the values.


1 Answers

from invoice in invoices
where invoice.IsPaid
from xr in invoice.InvoiceProducts
group xr.Quantity * xr.Price by xr.Product.Code into g
select new {Code = g.Key, SalesValue = g.Sum()};

If you want per invoice, then:

from invoice in invoices
where invoice.IsPaid
from xr in invoice.InvoiceProducts
group xr.Quantity * xr.Price
  by new {Code = xr.Product.Code, Invoice = invoice }
  into g
select new {
  Code = g.Key.Code,
  Invoice = g.Key.Invoice,
  SalesValue = g.Sum()};
like image 107
Amy B Avatar answered Sep 23 '22 06:09

Amy B