Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Define default value for SingleOrDefault Linq method

I try to get a data record ID from Entity Framework:

var plantAreaID = await db.PlantAreas
  .Where(p => p.Plant.CompanyNo == companyNo && p.Plant.Abbreviation == companyAbbr)
  .Select(p => p.ID)
  .SingleOrDefaultAsync();

The problem is, that there is a PlantArea with the ID 0. SingleOrDefault returns 0, though, if it doesn't find any record. So how can I differenciate between ID 0 and the case, where no data was found?

My first idea was to provide a default value -1, but SingleOrDefault doesn't seem to support that in this constellation.

How can I do that?

like image 389
André Reichelt Avatar asked Aug 28 '19 11:08

André Reichelt


People also ask

What is the default value of SingleOrDefault?

For a variable of a reference-type, the default value is null .

What is default value Linq?

The default value for reference and nullable types is null . The FirstOrDefault method does not provide a way to specify a default value.

What is the difference between FirstOrDefault () and SingleOrDefault () extension method in Linq?

SingleOrDefault() Vs. FirstOrDefault() in LINQ Query SingleOrDefault() – Same as Single(), but it can handle the null value. First() - There is at least one result, an exception is thrown if no result is returned. FirstOrDefault() - Same as First(), but not thrown any exception or return null when there is no result.

When should the SingleOrDefault () method be used?

When you want an exception to be thrown if the result set contains many records, use Single or SingleOrDefault. When you want a default value is returned if the result set contains no record, use SingleOrDefault. When you always want one record no matter what the result set contains, use First or FirstOrDefault.


2 Answers

null is the normal way to indicate missing values.

var plantAreaID = await db.PlantAreas
   .Where(p => p.Plant.CompanyNo == companyNo && p.Plant.Abbreviation == companyAbbr)
   .Select(p => new int?(p.ID))
   .SingleOrDefaultAsync();

If you want to use -1 to indicate a missing value, you can say

var plantAreaID = await db.PlantAreas
   .Where(p => p.Plant.CompanyNo == companyNo && p.Plant.Abbreviation == companyAbbr)
   .Select(p => new int?(p.ID))
   .SingleOrDefaultAsync() ?? -1;
like image 199
gnud Avatar answered Oct 13 '22 14:10

gnud


I found another solution, that doesn't require casting:

int plantAreaID = await db.PlantAreas
  .Where(p => p.Plant.CompanyNo == companyNo && p.Plant.Abbreviation == companyAbbr)
  .Select(p => p.ID)
  .DefaultIfEmpty(-1)
  .SingleAsync();
like image 22
André Reichelt Avatar answered Oct 13 '22 15:10

André Reichelt