Efcore: EFCore 2.1 - System.NullReferenceException: Object reference not set to an instance of an object. at Microsoft.EntityFrameworkCore.Extensions.Internal.EFPropertyExtensions.CreateEFPropertyExpression

Created on 3 Jul 2018  路  16Comments  路  Source: dotnet/efcore

I have just upgraded an existing project to EntityFrameworkCore 2.1

A query that was previously working is now throwing a null reference exception. I have put calls to .ToList() at various points through building up my query and it seems to be something to do with the call to automapper ProjectTo.

This doesn't happen for all my queries though.

This is the exception I am getting:

System.NullReferenceException: Object reference not set to an instance of an object.
   at Microsoft.EntityFrameworkCore.Extensions.Internal.EFPropertyExtensions.CreateEFPropertyExpression(Expression target, Type propertyDeclaringType, Type propertyType, String propertyName, Boolean makeNullable)
   at Microsoft.EntityFrameworkCore.Extensions.Internal.EFPropertyExtensions.CreateEFPropertyExpression(Expression target, IPropertyBase property, Boolean makeNullable)
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.EntityEqualityRewritingExpressionVisitor.RewriteNullEquality(ExpressionType nodeType, Expression nonNullExpression)
   at Microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.EntityEqualityRewritingExpressionVisitor.VisitBinary(BinaryExpression binaryExpression)
   at System.Linq.Expressions.BinaryExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitConditional(ConditionalExpression node)
   at System.Linq.Expressions.ConditionalExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberAssignment(MemberAssignment node)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberBinding(MemberBinding node)
   at System.Linq.Expressions.ExpressionVisitor.Visit[T](ReadOnlyCollection`1 nodes, Func`2 elementVisitor)
   at System.Linq.Expressions.ExpressionVisitor.VisitMemberInit(MemberInitExpression node)
   at System.Linq.Expressions.MemberInitExpression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Remotion.Linq.Clauses.SelectClause.TransformExpressions(Func`2 transformation)
   at Remotion.Linq.QueryModel.TransformExpressions(Func`2 transformation)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryOptimizer.Optimize(QueryCompilationContext queryCompilationContext, QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.OptimizeQueryModel(QueryModel queryModel, Boolean asyncQuery)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryModelVisitor.OptimizeQueryModel(QueryModel queryModel, Boolean asyncQuery)
   at Microsoft.EntityFrameworkCore.Query.EntityQueryModelVisitor.CreateQueryExecutor[TResult](QueryModel queryModel)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](QueryModel queryModel)
--- End of stack trace from previous location where exception was thrown ---
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](Expression query, IQueryModelGenerator queryModelGenerator, IDatabase database, IDiagnosticsLogger`1 logger, Type contextType)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass13_0`1.<Execute>b__0()
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQueryCore[TFunc](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.CompiledQueryCache.GetOrAddQuery[TResult](Object cacheKey, Func`1 compiler)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression)
   at Remotion.Linq.QueryableBase`1.GetEnumerator()
   at System.Collections.Generic.List`1.AddEnumerable(IEnumerable`1 enumerable)
   at System.Linq.Enumerable.ToList[TSource](IEnumerable`1 source)
   at Momenta.People.HierarchicalConfiguration.HierarchicalConfigurationController`3.GetConfiguration(ODataQueryOptions`1 queryOptions, Request`1 query) in D:\code\Momenta.People\src\Momenta.People\HierarchicalConfiguration\HierarchicalConfigurationController.cs:line 191
   at lambda_method(Closure , Object )
   at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()
   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)
   at System.Threading.Tasks.ValueTask`1.get_Result()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
   at Microsoft.AspNetCore.Builder.RouterMiddleware.Invoke(HttpContext httpContext)
   at Microsoft.AspNetCore.Localization.RequestLocalizationMiddleware.Invoke(HttpContext context)
   at NewOrbit.Mediatr.Authorisation.AspNetCore.AuthorisationFailureMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.StaticFiles.StaticFileMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Authentication.AuthenticationMiddleware.Invoke(HttpContext context)
   at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[TContext](IHttpApplication`1 application)

Further technical details

EF Core version: 2.1
Database Provider: Microsoft.EntityFrameworkCore.SqlServer
Operating system: Windows 10
IDE: Visual Studio 2017 15.7.4)

closed-duplicate customer-reported

Most helpful comment

For the original exception message Duplicate of #12738

All 16 comments

What's the object, what's the query, what's the automapper mapping profile set up?

I've done some further investigation and it seems that all of the classes this are failing with have a property called Type. As soon I comment this out of the models I am projecting to it works.

OK I have managed to reproduce this. Seems to be some combination of a GroupBy call and projecting to a model with a property named Type. Not sure why these specific situations cause this issue.

Can see repro here: https://github.com/hisuwh/EFAutomapperBugRepro

Worth noting that I tried without the group by clause also and this works fine so it seems to be some combination of these things

That issue does share the idea of having a .First() within a select, though it is strange with my issue that removing the Type property from the projection fixes the issue.

The issues appear to have the same underlying cause.
I read this issue before submitting mine and failed to see the similarity because I didn't inspect the sample you provided properly.

Specifically the issue is seen when accessing a collection of a child model within a .Select on a parent model.
The issue occurs in this code because the .GroupBy causes a collection of ThingTypeModels to be created, which is then accessed with .First

Removing the Type obviously stops the above condition from being true. You will also find no failure without the .GroupBy, because accessing a singular navigational property is not flawed. e.g. Type.Name

Edit:
To clarify: the issue is seen when accessing the child collection requires a JOIN . It appears that JOIN isn't happening when using .Select to project to a different model.

@smitpatel to follow up.

For further investigation, we need repro code which demonstrate the issue without using AutoMapper, OData libs and pure EF Core query.

@smitpatel removing the odata call doesn't change anything this issue still presents. But I am unable to reproduce without projecting using automapper.

I have tried both of these approaches:

// 1:
return queryable
    .GroupBy(t => t.TypeId)
    .Select(g => new ThingModel
    {
        Id = g.First().Id,
        Name = g.First().Name,
        TypeId = g.First().TypeId,
        Type = new ThingTypeModel
        {
            Id = g.First().Type.Id,
            Name = g.First().Type.Name
        }
    });

// 2:
return queryable
    .GroupBy(t => t.TypeId)
    .Select(g => g.First())
    .Select(t => new ThingModel
    {
        Id = t.Id,
        Name = t.Name,
        TypeId = t.TypeId,
        Type = new ThingTypeModel
        {
            Id = t.Type.Id,
            Name = t.Type.Name
        }
    });

But neither reproduced the issue. So it must be something specific about how automapper is calling Entity Framework. This issue only presented upon upgrading Entity Framework Core to 2.1

Maybe my issue can help shed some light?
After further tests, I only saw the problem when trying to include through 2 entities.

e.g.
This was fine:
.Include(x => x.Customers).ThenInclude(x => x.Location)

These were not:
.Include(x => x.Customers).ThenInclude(x => x.Location.Country)
or
.Include(x => x.Customers).ThenInclude(x => x.Location).ThenInclude(x => x.Country)

The SQL that was generated was missing the required JOINs. I found this after I noticed adding .ToList() before the .Select() caused the query to execute correctly. So I compared the SQL that was generated by the "faulty" code, to the SQL generated after adding .ToList() before the .Select().

I wonder if AutoMapper is causing a second JOIN, or a second entity step for some reason? The generated SQL should show if this is the case. I also wonder if adding that .ToList() will have the same effect here? This might also help decide whether these are being caused by the same underlying issue.

@MattOG its not generating SQL though as its throwing the exception before that?
I'm not doing any explicit includes either as that is handled by the projection.

EF Triage: We are still hoping that someone can provide a repro for this.

Try again...
This error exhibits behaviour similar to the issue I reported. Using a .ToList() to execute the query before projecting with the .Select() works. Projecting through two objects fails: .Collection().Object.Object.Property ...
I'm unsure as to why AutoMapper is causing an object graph deep enough to trigger this error from a single .GroupBy(), but maybe the code I have will help find the problem:

https://github.com/MattOG/WebErrorSample

@MattOG - Your issue is #8526

For the original exception message Duplicate of #12738

Was this page helpful?
0 / 5 - 0 ratings