Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to handle nulls in LINQ when using Min or Max?

Tags:

c#

.net

null

linq

I have the following Linq query:

result.Partials.Where(o => o.IsPositive).Min(o => o.Result) 

I get an exception when result.Partials.Where(o => o.IsPositive) does not contains elements. Is there an elegant way to handle this other than splitting the operation in two and checking for null? I have a class full of operations like this one.

EDIT: The question is related with LINQ to Objects.

This is the Exception I'm getting (translated it says: The sequence is empty):

enter image description here

like image 398
Ignacio Soler Garcia Avatar asked Mar 24 '12 14:03

Ignacio Soler Garcia


People also ask

How do you handle null values in LINQ query?

An object collection such as an IEnumerable<T> can contain elements whose value is null. If a source collection is null or contains an element whose value is null , and your query doesn't handle null values, a NullReferenceException will be thrown when you execute the query. var query1 = from c in categories where c !=

Will Linq select return null?

in conclusion no, it won't return null since null can't say sequence contains no elements it will always say object reference not set to an instance of an object ;) Oh, your explanation helps further understanding.

Is null in LINQ to SQL?

In SQL Server, a SQL statement like 'NULL=NULL' evaluates to false. however 'NULL IS NULL' evaluates to true. So, for NULL values in your database columns, you need to use the 'IS' operator instead of the regular '=' operator.


2 Answers

A short summary of the calculation of a Min

- No mediation (Exception!)

   var min = result.Partials.Where(o => o.IsPositive).Min(o => o.Result); 

This is your case: if there are no matching elements, then the Min call will raise an exception (InvalidOperationException).

- With DefaultIfEmpty() -- still troublesome

 var min = result.Partials.Where(o => o.IsPositive)                           .Select(o => o.Result)                           .DefaultIfEmpty()                           .Min(); 

DefaultIfEmpty will create an enumeration over the 0 element, when there are no elements in the list. How do you know that 0 is the Min or if 0 stands for a list with no elements?

- Nullable values; A better solution

   var min = result.Partials.Where(o => o.IsPositive)                             .Min(o => (decimal?)o.Result); 

Here Min is either null (because that's equal to default(decimal?)) or the actual Min found.

So a consumer of this result will know that:

  1. When result is null then the list had no elements
  2. When the result is a decimal value then the list had some elements and the Min of those elements is that returned value.

However, when this doesn't matter, then min.GetValueOrDefault(0) can be called.

like image 144
Adrian Iftode Avatar answered Sep 20 '22 08:09

Adrian Iftode


You can use the DefaultIfEmpty method to ensure the collection has at least 1 item:

result.Partials.Where(o => o.IsPositive).Select(o => o.Result).DefaultIfEmpty().Min(); 
like image 26
Kendall Frey Avatar answered Sep 23 '22 08:09

Kendall Frey