Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

LINQ SUM data based on Array Results

Tags:

c#

linq

I'm stuck on this issue. I know it can be done nicely with LINQ (I don't want to use multiple foreach loops), but I simply cannot get it to work. Here is the problem:

I have two classes:

Class Invoice

public class Invoice
{
public int InvoiceID { get; set; }
public string Name { get; set; }
public DateTime DueDate { get; set; }

public Invoice(int ID, string sName, DateTime dt_Date)
{
    this.InvoiceID = ID;
    this.Name = sName;
    this.DueDate = dt_Date;
}
}

and Class Activity

public class Activity
{
    public int ActivityID { get; set; }
    public int InvoiceID { get; set; }
    public int Count { get; set; }
    public double Price { get; set; }

    public Activity(int ID, int InvoiceID, int iCount, double dPrice)
    {
        this.ActivityID = ID;
        this.InvoiceID = InvoiceID;
        this.Count = iCount;
        this.Price = dPrice;
    }
}

The logic is that Each Invoice contains multiple Activities. E.g. you have a bill from a shop (Invoice), which includes items such as bread, butter, milk (Activities).

What I want to do is that based on user selected Date, I want to return total amount paid (basically I want to perform SUM of all bills from specific Date period).

Here is what I have:

//user selected DateTime - for the sake of test we make it current day
DateTime selectedDate = DateTime.Now;

//Retrieve invocies that match user selected Date
var retrievedInvoices = invList
  .Where(n => n.DueDate.ToShortDateString() == selectedDate.ToShortDateString());

This is fine, as we have retrieved list of all Invoices based on desired Date. But now? I tried something as following:

//now make SUM of activities that match retrievedInvoices -> look at their 
//ID's and if match is found, then multiply price x count
double dResult = invActivity
    .Where(n => retrievedInvoices.Where(x=>x.InvoiceID == n.InvoiceID))
    .Sum(n => n.Price * n.Count);

But it is not working. I am not that proficient in LINQ so there might be more elegant way of doing it (maybe in one line of code) but I don't know.

Could you guys help me with this one, please?

EDIT:

Interesting thing to note also for others that might be looking at this thread: I have first tried to use List in order to retrieve my list of invoices that match specific time period (DateTime_From and DateTime_To); but it behaved strangely as sometimes it worker correctly, sometimes not (even though the code was correct). After I changed List <Invoice> retrievedInvoice to var retrievedInvoice it suddenly worked without a problem. I don't understand why this is so, but I will definitely be more aware next time of what type do I use. Thanks again folks!

like image 704
Robert J. Avatar asked Mar 10 '26 23:03

Robert J.


1 Answers

Your code looks fine, but try some changes like this:

use .Date to compare just Dates without Time (hours, minutes, etc..) and select just eh InvoiceID proeprty into a array

var retrievedInvoices = invList.Where(n => n.DueDate.Date == selectedDate.Date)
                               .Select(x => x.InvoiceID);

use .Contains() to check the condition which return a bool value.

double dResult = invActivity
    .Where(n => retrievedInvoices.Contains(n.InvoiceID))
    .Sum(n => n.Price * n.Count);

Some changes was suggested by Tuespetre user in comments bellow!

like image 146
Felipe Oriani Avatar answered Mar 12 '26 13:03

Felipe Oriani



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!