Null reference exception being thrown in EF LINQ query if-clause

13,913

Solution 1

It sounds like this might be a bug in EF Core (but I don't know this for sure).

One thing you might try is to fail fast if the base requirements of plan are not met, and more importantly, instead of using the ternary operator, use the traditional comparison operators along with parenthesis:

public IEnumerable<Plan> GetPlans(Plan plan)
{
    if (plan == null) return new List<Plan>();

    return _context.Plans
        .Where(e =>
            e.Situation == plan.Situation &&
            e.Notes.Contains(plan.Notes) &&
            (plan.Exercise == null || 
            plan.Exercise.Year <= 0 || 
            e.Excercise.Year == plan.Exercise.Year))
        .ToList();
}

Solution 2

To avoid this issue, make sure that you are not evaluating on null object.

var exercice = await _repositoryExercice.FirstOrDefaultAsync(i => i.IsCurrent);
var depenses = _repositoryDepense.GetAll()
                .Where( e => e.ExerciceId.Equals(exercice.Id))
                .WhereIf(AbpSession.TenantId.HasValue, m => m.TenantId.Value.Equals(AbpSession.TenantId.Value))
                .ToList();

The issue was causing by this line .Where( e => e.ExerciceId.Equals(exercice.Id)) because the variable exercice is null.

Best practice, I replaced that line by this :

...
.WhereIf(exercice != null, e => e.ExerciceId.Equals(exercice.Id))
...
Share:
13,913
thiagoprzy
Author by

thiagoprzy

ASP.NET C# developer. Loves challenges, beautiful codes and rock n' roll.

Updated on June 15, 2022

Comments

  • thiagoprzy
    thiagoprzy almost 2 years

    I couldn't find the exact words to explain what's happening, so if this is a duplicated question, I apologize.

    I tried to do a quite simple AND condition if-clause inside a LINQ Query, in order to check if an object is null and then verify if its property is equal or not the column I wanted to compare.

    The code:

    public IEnumerable<Plan> GetPlans(Plan plan)
        {
            return _context.Plans.Where(e =>
                e.Situation == plan.Situation &&
                e.Notes.Contains(plan.Notes) &&
                (plan.Excercise != null && plan.Exercise.Year > 0 ? e.Exercise.Year == plan.Exercise.Year: true)).ToList();
        }
    

    I've already done this kind of check a dozen times before in .NET 4.5, without having any kind of issue.

    But now, in the first .NET Core 2.0 project I'm working on, I had the following error:

    An exception was thrown while attempting to evaluate a LINQ query parameter expression. To show additional information call EnableSensitiveDataLogging() when overriding DbContext.OnConfiguring.
    

    The inner exception is clearer: NULL REFERENCE EXCEPTION.

    After some tests, I found out that the error happens when plan.Exercise comes null, even if I try to avoid the exception by checking at first if it's null or not.

    If I try to do the same check directly in Immediate Window, it returns "false", as it should be.

    Am I missing something here? It could be an EF bug? Any particular reason why this works in .NET 4.5, for example, and not in .NET Core 2.0?

    Thanks in advance.

    UPDATE

    Ivan's solution did the job:

    Rewrite ? : constructs with equivalent ||

    plan.Excercise == null || plan.Exercise.Year <= 0 || e.Excercise.Year == plan.Exercise.Year