Reputation: 60604
I have an entity in my model that has an integer property:
public class Foo
{
public int SortOrder { get; set; }
// ...other props
}
Now, for some subset of all the Foo
s in the database, I want to select the highest SortOrder
and add one - i.e. get the sort order for a new object added last in the collection - but if there are no Foo
s in that subset, I want to end up with 0 - i.e. the sort order of a new object added to an empty collection.
Reading this reference page, I got the impression that .Max()
returns null
if the collection over which it aggregates is empty, so I tried the following:
var sortOrder = context.Foos
.Where(/* predicate for subset */)
.Max(foo => foo.SortOrder) + 1
?? 0;
but that doesn't compile, since the return type of .Max
is inferred to be int
which can't be null coalesced.
However, if I just don't use the null coalescing, and assume that .Max()
really returns default(T)
(i.e. 0
in this case), then I'll end up with 1
instead of 0
for the empty case. Since this is a call to the database, I'd rather make do with one query.
It works just as I want it to if I make the property on Foo
to be of type int?
, but I don't want to do that since we don't allow NULL
values in the database and I see no reason to allow them on the entity then.
Upvotes: 1
Views: 641
Reputation: 460158
I got the impression that .Max() returns null if the collection over which it aggregates is empty
You get an InvalidOperationException
which is documented here
"InvalidOperationException... source does not contain any elements."
You can use DefaultIfEmpty(0)
:
int maxSortOrder = context.Foos
.Where(/* predicate for subset */)
.Select(foo => foo.SortOrder + 1)
.DefaultIfEmpty(0)
.Max();
Upvotes: 3