If the query is empty, the maximum return value

.net c# entity-framework lambda linq

Question

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?

1
167
10/7/2018 5:09:24 PM

Accepted Answer

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

The zero in DefaultIfEmpty is not necessary.

288
5/27/2014 11:44:29 AM

Popular Answer

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.



Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow