8

When my model has values, i can get the average easily with this code

@Model.Where(a => a.count!= null).Average(a => a.totalday).ToString()

For example:

count = 7 totalday= 3 average= 2.33

But i can't get average value when my model values equals to null or zero. As you know we can't divide 0 to 0 or null to null.

I mean;

count = 0 or null; totalday= 0 or null; average= ????

If all values are null, how can i write my table to "0" or a string like "there is no any average"

I tried lots of things but i get an error.

kojirosan
  • 497
  • 10
  • 25
  • 1
    You could try `@Model.Where(a => a.count!= null).DefaultIfEmpty(0).Average(a => a.totalday).ToString()`? – chridam Sep 10 '14 at 11:10
  • thank you for quick reply. i get this error: An exception of type 'System.NullReferenceException' occurred in "....dll" but was not handled in user code – kojirosan Sep 10 '14 at 11:14
  • That's becasue the default value for whatever `Model` returns is `null`. Either provide another default or use the solution I have below which first projects to the `totaldays`. – Dirk Sep 10 '14 at 11:19
  • possible duplicate of [Error in linq query when using average](http://stackoverflow.com/questions/19009901/error-in-linq-query-when-using-average) – Amit Sep 10 '14 at 11:22

2 Answers2

24

It really depends on what you want do do. If you're ok with having some sort of default value for the average then you can use DefaultIfEmpty

@Model.Where(a => a.count!= null)
      .Select(a => a.totalday)
      .DefaultIfEmpty(0)
      .Average()
      .ToString()

But if it would be better to display something else entirely then you'll have to first check whether there are any elements in the filtered sequence.

Dirk
  • 10,668
  • 2
  • 35
  • 49
1

There's no problem with zero's in your list.

var list = new List<int>{ 0,1,2,3,4,5,6};
var avg = list.Average(); // avg = 3

You might want to take care of your nulls though, but you can filter them out like easily with:

var not_null_list = some_list.Where(item => item != null);

From there, you should be ok (Unless you need to account for numbers which are null, which doesn't make much sense I think ....)

Edit:
I see your dilemma. I would suggest the following in that case :)

var list = new List<int>{};
string answer;
if (list.Any ())
    answer = list.Average();
else
    answer = "User is a shmartsy pants. Try again with valid data";
Noctis
  • 11,507
  • 3
  • 43
  • 82
  • 1
    The problem is if there are **only** nulls in the list or if the list is empty to begin with, in which case `Average` will throw an exception. – Dirk Sep 10 '14 at 11:28