2
  public async Task<ParagemRegisto> GetParagemRegistoOnGoingAsync(int registoId)
  {
        return await = _context.ParagensRegistos
            .Where(pr => pr.RegistoId == registoId && pr.HoraFim == null)
            .FirstAsync();
  }

This causes a null reference exception when there's no records found. How can I make it so it returns null if that is the case?

marc_s
  • 732,580
  • 175
  • 1,330
  • 1,459
Jackal
  • 3,359
  • 4
  • 33
  • 78
  • 2
    I think you want `FirstOrDefaultAsync`, but that shouldn't give you a null exception for no records, it should give an `InvalidOperationException`. – juharr Jun 24 '19 at 19:49
  • Possible duplicate of [When to use .First and when to use .FirstOrDefault with LINQ?](https://stackoverflow.com/questions/1024559/when-to-use-first-and-when-to-use-firstordefault-with-linq) – Stefan Jun 24 '19 at 19:49
  • 1
    @juharr FirstOrDefaultAsync would not throw InvalidOperationException. It would return the default value. – Shahzad Jun 24 '19 at 19:52
  • I see, i been using linq awhile but still don't know much about it. I thought it was basically the same. Thanks for clearing up – Jackal Jun 24 '19 at 19:53
  • @Jackal You are welcome. Default when used does not throw exceptions. Same is the case with SIngleOrDefault – Shahzad Jun 24 '19 at 19:56
  • @Shahzad I mean that `FirstAsync` would throw `InvalidOpertionException` and not a null reference exception. – juharr Jun 25 '19 at 13:27

3 Answers3

4

You can use FirstOrDefaultAsync, if it does not exist, returns null, but an exception does not occur.

  public async Task<ParagemRegisto> GetParagemRegistoOnGoingAsync(int registoId)
  {
     return await = _context.ParagensRegistos.FirstOrDefaultAsync(pr => pr.RegistoId == registoId && pr.HoraFim == null);
  }
3

You can use FirstOrDefaultAsync.

Mustafa Gursel
  • 782
  • 1
  • 7
  • 16
2
public async Task<ParagemRegisto> GetParagemRegistoOnGoingAsync(int registoId)
{
    var result = await _context.ParagensRegistos
        .Where(pr => pr.RegistoId == registoId && pr.HoraFim == null)
        .FirstOrDefaultAsync();

    return result ?? new List<ParagemRegisto>();
}

FirstOrDefaultAsync would always return the default value instead of throwing an exception. So if there are no records, you could check what was returned. In this case we are checking for null, and if it does we try to return an empty list instead.

Shahzad
  • 1,677
  • 1
  • 12
  • 25
  • can you explain to me why is ?? returning a new list? – Jackal Jun 24 '19 at 19:53
  • 1
    @Jackal if the left side of the `??` operator evaluates to null, the right side is evaluated. Read more on the null coalescing operator [here](https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-coalescing-operator). – Tobias Tengler Jun 24 '19 at 19:54
  • 2
    @Jackal It usually is always better to return empty collections rather than null. ?? will check if the result is null. If that is the case, it will return an empty list instead, so that the consumer of the method does not run into problems if they do not explicitly check for null return values – Shahzad Jun 24 '19 at 19:54
  • 2
    @Shahzad your answer is of course correct code-wise, but as you can tell from OP's comments, he is new to LINQ and most likely C# as well. I believe it would be helpful to also explain what your code is doing opposed to OP's original code. It will also improve the quality of your answer! – Tobias Tengler Jun 24 '19 at 19:57
  • @TobiasTengler Thanks for the comment. Would keep this in mind for future answers ! – Shahzad Jun 24 '19 at 19:59
  • Am I missing something here or is that a mistake? `result` is of type `ParagemRegisto`, and if it is `null` you return something of type `List`. As far as C# is concerned, this is not correct - as the signature of the function tells, you have to return an object of type `ParagemRegisto` in both cases or change it to `public async Task> [...]` and return an object of type `List` in both cases. – josibu Jun 21 '21 at 05:07