Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Max return value if empty query

I have this query:

int maxShoeSize = Workers
    .Where(x => x.CompanyId == 8)
    .Max(x => x.ShoeSize);

What will be in maxShoeSize if company 8 has no workers at all?

UPDATE:
How can I change the query in order to get 0 and not an exception?

like image 500
Naor Avatar asked Oct 14 '22 10:10

Naor


2 Answers

int maxShoeSize = Workers.Where(x => x.CompanyId == 8)
                         .Select(x => x.ShoeSize)
                         .DefaultIfEmpty(0)
                         .Max();

The zero in DefaultIfEmpty is not necessary.

like image 377
Ron K. Avatar answered Oct 17 '22 00:10

Ron K.


I know this is an old question and the accepted answer works, but this question answered my question about whether such an empty set would result in an exception or a default(int) result.

The accepted answer however, while it does work, isn't the ideal solution IMHO, which isn't given here. Thus I am providing it in my own answer for the benefit of anyone who is looking for it.

The OP's original code was:

int maxShoeSize = Workers.Where(x => x.CompanyId == 8).Max(x => x.ShoeSize);

This is how I would write it to prevent exceptions and provide a default result:

int maxShoeSize = Workers.Where(x => x.CompanyId == 8).Max(x => x.ShoeSize as int?) ?? 0;

This causes the return type of the Max function to be int?, which allows the null result and then the ?? replaces the null result with 0.


EDIT
Just to clarify something from the comments, Entity Framework doesn't currently support the as keyword, so the way to write it when working with EF would be:

int maxShoeSize = Workers.Where(x => x.CompanyId == 8).Max<[TypeOfWorkers], int?>(x => x.ShoeSize) ?? 0;

Since the [TypeOfWorkers] could be a long class name and is tedious to write, I've added an extension method to help out.

public static int MaxOrDefault<T>(this IQueryable<T> source, Expression<Func<T, int?>> selector, int nullValue = 0)
{
    return source.Max(selector) ?? nullValue;
}

This only handles int, but the same could be done for long, double, or any other value type you need. Using this extension method is very simple, you just pass in your selector function and optionally include a value to be used for null, which defaults to 0. So the above could be rewritten like so:

int maxShoeSize = Workers.Where(x => x.CompanyId == 8).MaxOrDefault(x => x.ShoeSize);

Hopefully that helps people out even more.

like image 77
CptRobby Avatar answered Oct 17 '22 00:10

CptRobby