Max return value if empty query
Solution 1:
int maxShoeSize = Workers.Where(x => x.CompanyId == 8)
.Select(x => x.ShoeSize)
.DefaultIfEmpty(0)
.Max();
The zero in DefaultIfEmpty
is not necessary.
Solution 2:
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.
Solution 3:
Max() won't return anything in that case.
It will raise InvalidOperationException since the source contains no elements.
Solution 4:
int maxShoeSize = Workers.Where(x => x.CompanyId == 8)
.Select(x => x.ShoeSize)
.DefaultIfEmpty()
.Max();
Solution 5:
If this is Linq to SQL, I don't like to use Any()
because it results in multiple queries to SQL server.
If ShoeSize
is not a nullable field, then using just the .Max(..) ?? 0
will not work but the following will:
int maxShoeSize = Workers.Where(x = >x.CompanyId == 8).Max(x => (int?)x.ShoeSize) ?? 0;
It absolutely does not change the emitted SQL, but it does return 0 if the sequence is empty because it changes the Max()
to return an int?
instead of an int
.