Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

Closed
hisuwh opened this issue Jul 3, 2018 · 16 comments

Comments

@hisuwh
Copy link

hisuwh commented Jul 3, 2018

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)

@kjbetz
Copy link

kjbetz commented Jul 3, 2018

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

@hisuwh
Copy link
Author

hisuwh commented Jul 3, 2018

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.

@hisuwh
Copy link
Author

hisuwh commented Jul 3, 2018

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

@hisuwh
Copy link
Author

hisuwh commented Jul 3, 2018

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

@kjbetz
Copy link

kjbetz commented Jul 3, 2018

This seems similar: #12534

@hisuwh
Copy link
Author

hisuwh commented Jul 4, 2018

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.

@MattOG
Copy link

MattOG commented Jul 4, 2018

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.

@ajcvickers
Copy link
Contributor

@smitpatel to follow up.

@smitpatel
Copy link
Contributor

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

@hisuwh
Copy link
Author

hisuwh commented Jul 10, 2018

@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

@MattOG
Copy link

MattOG commented Jul 10, 2018

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.

@hisuwh
Copy link
Author

hisuwh commented Jul 10, 2018

@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.

@divega
Copy link
Contributor

divega commented Jul 11, 2018

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

@MattOG
Copy link

MattOG commented Jul 13, 2018

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

@divega divega added this to the 2.2.0 milestone Jul 16, 2018
@smitpatel
Copy link
Contributor

@MattOG - Your issue is #8526

@smitpatel
Copy link
Contributor

For the original exception message Duplicate of #12738

@smitpatel smitpatel removed this from the 2.2.0 milestone Aug 1, 2018
@ajcvickers ajcvickers reopened this Oct 16, 2022
@ajcvickers ajcvickers closed this as not planned Won't fix, can't repro, duplicate, stale Oct 16, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

7 participants