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

Object reference not set to an instance of an object exception when using NET Topology Suite in Select projection #23336

Closed
appimpact opened this issue Nov 15, 2020 · 3 comments
Assignees
Labels
area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported regression Servicing-approved type-bug
Milestone

Comments

@appimpact
Copy link

appimpact commented Nov 15, 2020

After the upgrade from .NET Core 3.1 to .NET 5.0, we have noticed a systematic error on all our queries that include NET Topology Suite but only within certain scenarios when there is a nested Select statement.

Those queries are now throwing 'Object reference not set to an instance of an object' exception.

Full example can be found here:
https://github.com/App-Impact-Labs/ISSUE-EFNetTopologySuiteProjectionQueryError

In the example above, we have three entities:

    public class MedicalService
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public virtual IList<HealthInstitutionMedicalServiceLink> HealthInstitutionLinks { get; set; }
    }
    public class HealthInstitution
    {
        public int Id { get; set; }

        public string Name { get; set; }

        public Point Coordinates { get; set; }

        public virtual IList<HealthInstitutionMedicalServiceLink> MedicalServiceLinks { get; set; }
    }
    public class HealthInstitutionMedicalServiceLink
    {
        public int Id { get; set; }

        public int HealthInstitutionId { get; set; }
        public virtual HealthInstitution HealthInstitution { get; set; }

        public int MedicalServiceId { get; set; }
        public virtual MedicalService MedicalService { get; set; }
    }
  1. This query works (coordinates are commented out):
            HealthInstitutionGetDetailsRes dto = dbContext.HealthInstitutions
                .Select(hi => new HealthInstitutionGetDetailsRes
                {
                    Id = hi.Id,
                    Name = hi.Name,
                        //Coordinates = new HealthInstitutionGetDetailsRes.GeolocationDto
                        //{
                        //    Latitude = hi.Coordinates.Y,
                        //    Longitude = hi.Coordinates.X
                        //},
                        MedicalServiceIds = hi.MedicalServiceLinks.Select(msl => msl.MedicalServiceId)
                })
                .FirstOrDefault();
  1. This one works also (ids are commented out):
            HealthInstitutionGetDetailsRes dto = dbContext.HealthInstitutions
                .Select(hi => new HealthInstitutionGetDetailsRes
                {
                    Id = hi.Id,
                    Name = hi.Name,
                    Coordinates = new HealthInstitutionGetDetailsRes.GeolocationDto
                    {
                        Latitude = hi.Coordinates.Y,
                        Longitude = hi.Coordinates.X
                    },
                    //MedicalServiceIds = hi.MedicalServiceLinks.Select(msl => msl.MedicalServiceId)
                })
                .FirstOrDefault();
  1. However full query with both coordinates and ids is not working (throws an exception):
            HealthInstitutionGetDetailsRes dto = dbContext.HealthInstitutions
                .Select(hi => new HealthInstitutionGetDetailsRes
                {
                    Id = hi.Id,
                    Name = hi.Name,
                    Coordinates = new HealthInstitutionGetDetailsRes.GeolocationDto
                    {
                        Latitude = hi.Coordinates.Y,
                        Longitude = hi.Coordinates.X
                    },
                    MedicalServiceIds = hi.MedicalServiceLinks.Select(msl => msl.MedicalServiceId)
                })
                .FirstOrDefault();

Include stack traces

   at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SqlFunctionExpression.GetHashCode()
   at System.Collections.Generic.Dictionary`2.TryInsert(TKey key, TValue value, InsertionBehavior behavior)
   at Microsoft.EntityFrameworkCore.Query.SqlExpressions.SelectExpression.PushdownIntoSubquery()
   at Microsoft.EntityFrameworkCore.Query.Internal.CollectionJoinApplyingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at System.Linq.Expressions.Expression.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 Microsoft.EntityFrameworkCore.Query.Internal.CollectionJoinApplyingExpressionVisitor.VisitExtension(Expression extensionExpression)
   at System.Linq.Expressions.Expression.Accept(ExpressionVisitor visitor)
   at System.Linq.Expressions.ExpressionVisitor.Visit(Expression node)
   at Microsoft.EntityFrameworkCore.Query.RelationalQueryTranslationPostprocessor.Process(Expression query)
   at Microsoft.EntityFrameworkCore.Query.QueryCompilationContext.CreateQueryExecutor[TResult](Expression query)
   at Microsoft.EntityFrameworkCore.Storage.Database.CompileQuery[TResult](Expression query, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.CompileQueryCore[TResult](IDatabase database, Expression query, IModel model, Boolean async)
   at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass9_0`1.<Execute>b__0()
   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 System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source)

Include provider and version information

EF Core version: 5.0.0
Database provider: Microsoft.EntityFrameworkCore.SqlServer
Target framework: .NET 5.0
Operating system: Windows 10 Enterprise
IDE: Visual Studio 2019 16.8.0

@maumar
Copy link
Contributor

maumar commented Nov 16, 2020

I verified this reproduces with 5.0 bits but works correctly on current main. Generated sql:

SELECT [t].[Id], [t].[Name], [t].[c], [t].[c0], [h0].[MedicalServiceId], [h0].[Id]
FROM (
    SELECT TOP(1) [h].[Id], [h].[Name], [h].[Coordinates].Lat AS [c], [h].[Coordinates].Long AS [c0]
    FROM [HealthInstitutions] AS [h]
) AS [t]
LEFT JOIN [HealthInstitutionMedicalServiceLinks] AS [h0] ON [t].[Id] = [h0].[HealthInstitutionId]
ORDER BY [t].[Id], [h0].[Id]

@smitpatel
Copy link
Contributor

This 43a5493#diff-a307bbe9617539d71c4d3d72606c8b7328be03419f04e034b1e492977ca82aa3 fixed it. But we can extract out fix here for patch if needed. It is missing a null check in hash computation.

@appimpact
Copy link
Author

We have to do query splitting to fix our systems, so if it is possible to embed this for the next patch it would be appreciated.

@ajcvickers ajcvickers added this to the 5.0.1 milestone Nov 16, 2020
@smitpatel smitpatel added closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. type-bug labels Nov 16, 2020
@ajcvickers ajcvickers added Servicing-approved closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. and removed closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. labels Nov 21, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
area-query closed-fixed The issue has been fixed and is/will be included in the release indicated by the issue milestone. customer-reported regression Servicing-approved type-bug
Projects
None yet
Development

No branches or pull requests

5 participants