How to force LINQ Sum() to return 0 while source collection is empty

C#.NetEntity Framework

C# Problem Overview


Basically when I do the following query, if no leads were matched the following query throws an exception. In that case I'd prefer to have the sum equalize 0 rather than an exception being thrown. Would this be possible in the query itself - I mean rather than storing the query and checking query.Any() ?

double earnings = db.Leads.Where(l => l.Date.Day == date.Day
                && l.Date.Month == date.Month
                && l.Date.Year == date.Year
                && l.Property.Type == ProtectedPropertyType.Password
                && l.Property.PropertyId == PropertyId).Sum(l => l.Amount);

C# Solutions


Solution 1 - C#

Try changing your query to this:

db.Leads.Where(l => l.Date.Day == date.Day
            && l.Date.Month == date.Month
            && l.Date.Year == date.Year
            && l.Property.Type == ProtectedPropertyType.Password
            && l.Property.PropertyId == PropertyId)
         .Select(l => l.Amount)
         .DefaultIfEmpty(0)
         .Sum();

This way, your query will only select the Amount field. If the collection is empty, it will return one element with the value of 0 and then the sum will be applied.

Solution 2 - C#

I prefer to use another hack:

double earnings = db.Leads.Where(l => l.Date.Day == date.Day
                                      && l.Date.Month == date.Month
                                      && l.Date.Year == date.Year
                                      && l.Property.Type == ProtectedPropertyType.Password
                                      && l.Property.PropertyId == PropertyId)
                          .Sum(l => (double?) l.Amount) ?? 0;

Solution 3 - C#

Try this instead, it's shorter:

db.Leads.Where(..).Aggregate(0, (i, lead) => i + lead.Amount);

Solution 4 - C#

That's win for me:

int Total = 0;
Total = (int)Db.Logins.Where(L => L.id == item.MyId).Sum(L => (int?)L.NumberOfLogins ?? 0);

In my LOGIN table, in field NUMBEROFLOGINS some values are NULL and others have an INT number. I sum here total NUMBEROFLOGINS of all users of one Corporation (Each Id).

Solution 5 - C#

Try:

> double earnings = db.Leads.Where(l => l.ShouldBeIncluded).Sum(l => > (double?) l.Amount) ?? 0;

The query "SELECT SUM([Amount])" will return NULL for empty list. But if you use LINQ it expects that the "Sum(l => l.Amount)" returns double and it doesn't allow you to use "??" operator to set 0 for empty collection.

In order to avoid this situation you need to make LINQ expect "double?". You can do it by casting "(double?)l.Amount".

It doesn't affect the query to SQL but it makes LINQ working for empty collections.

Solution 6 - C#

db.Leads.Where(l => l.Date.Day == date.Day
        && l.Date.Month == date.Month
        && l.Date.Year == date.Year
        && l.Property.Type == ProtectedPropertyType.Password
        && l.Property.PropertyId == PropertyId)
     .Select(l => l.Amount)
     .ToList()
     .Sum();

Solution 7 - C#

Another option is to cast the value, as in the code below

(decimal?)(x.TicketDetails.Sum(y => y.Cost *y.Qty)) ?? 0

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionJohn MayerView Question on Stackoverflow
Solution 1 - C#Simon BelangerView Answer on Stackoverflow
Solution 2 - C#tukaefView Answer on Stackoverflow
Solution 3 - C#Kovács RóbertView Answer on Stackoverflow
Solution 4 - C#Pedro RamosView Answer on Stackoverflow
Solution 5 - C#Maxim LukoshkoView Answer on Stackoverflow
Solution 6 - C#MonaView Answer on Stackoverflow
Solution 7 - C#Pepe0217View Answer on Stackoverflow