Efcore: Scaffolding No Longer Works With NetTopologySuite

Created on 26 Sep 2019  路  12Comments  路  Source: dotnet/efcore

Follow up from https://github.com/NetTopologySuite/NetTopologySuite/issues/349#i

Steps to reproduce

  1. Follow steps in https://docs.microsoft.com/en-us/ef/core/get-started/index?tabs=netcore-cli
  2. Before running initial create

    • add package Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite version 3.0.0

    • Add a property of type Point, eg: public Point Location { get; set; }

  3. Exception occurs when trying to map the Point property:
System.InvalidOperationException: The property 'Point.UserData' could not be mapped, because it is of type 'object' which is not a supported primitive type or a valid entity type. Either explicitly map this property, or ignore it us
ing the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.ValidatePropertyMapping(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Sqlite.Internal.SqliteModelValidator.Validate(IModel model, IDiagnosticsLogger`1 logger)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.ValidatingConvention.ProcessModelFinalized(IConventionModelBuilder modelBuilder, IConventionContext`1 context)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelFinalized(IConventionModelBuilder modelBuilder)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelFinalized(IConventionModelBuilder modelBuilder)
   at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.FinalizeModel()
   at Microsoft.EntityFrameworkCore.ModelBuilder.FinalizeModel()
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.<>c__DisplayClass5_0.<GetModel>b__1()
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at System.Lazy`1.get_Value()
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder)
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
   at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_3(IServiceProvider p)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType
)

See attached sample project.
ef-core-3-point-bug.zip

Further technical details

EF Core version: 3.0.0
Database provider: Microsoft.EntityFrameworkCore.SqlServer and Microsoft.EntityFrameworkCore.Sqlite tested
Target framework: .NET Core 3.0
Operating system: Windows 10
IDE: Command line

closed-question customer-reported

All 12 comments

How comes something that fundamental is not unit tested? I mean, there should be a test whether nettopoligy mapping works - quite some. And if it blows at this point,.... something really is not tested.

@andrejohansson Are you missing a call to UseNetTopologySuite? It looks like it's trying to map it as a regular entity type.

options.UseSqlite(connectionString, x => x.UseNetTopologySuite())

I did not make wild accusations. I asked how this could not be tested - and your answer that it was simply not initialized and works when done so is already an answer.

Obviously you are loaded with accusations - probably because there are a LOT of people like me stuck with workaround for the new little issues of the new and wonderfull efcore. Stuck on 2.2 for now loading all data into memory on every request because otherwise I get invalid issues. Yes, I know thigns MAY work with 3.0 - bu t the SQL there looks awfull and sql generation is "amazingly slow". So, I wait for 3.1 and give is anotehr try then.

Until then - i.e. until EF Core is usabne in a complex real world scenario - I am frustrated and EXPECT efcore to overlook the obvious little issues. After all, they did overlook how global filters totally broke queries in certain scenarios.

But this was really NOT an accusation but a honest question.

I agree we're missing a lot of fundamental coverage. I've filed #17018 and #17618 to help us address the problem.

@bricelam I am missing it in the supplied example that is true. However when I check my production code where I first got the error I still have it:

      return builder
                .UseLazyLoadingProxies()
                .UseSqlServer(connectionString,
                    // For spatial data
                    x => x
                        .UseNetTopologySuite()
                        .EnableRetryOnFailure());

I will verify again tomorrow at work, maybe the initialization for the ef command isn麓t getting properly initialized in my case (there was changes to how ef command initialized and we now need to create a factory for the command). Thank you for your help!

Sounds good, be sure to review Design-time DbContext Creation to make sure you're using the best pattern for your app.

I have nog checked and can confirm, I had created a design time factory from the guide you mentioned and this factory method did not include .UseNetTopologySuite().

Changing the factory so that it replicates my Startup.cs configuration solved the problem.

Thanks for your help!

@bricelam
I can create a new issue, but I'm having a similar issue. I have an MVC app that targets NET Core 3.1. A class lib for entities and another for DAL (which contains my DbContext) that targets NET Standard 2.0. I installed Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite 3.1.3 into all three projects. I have an class that includes a property of type Point. I included a call to .UseNetTopologySuite().

Inside of Startup.cs

        public void ConfigureServices(IServiceCollection services)
        {
            services.AddDbContext<SmContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), x => x.UseNetTopologySuite()));
            services.AddDbContext<SmMigrationDbContext>(options =>
                options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), x => x.UseNetTopologySuite()));
        }

When I Add-Migration, I get the following error:

The property 'SupplierAddress.Point' is of type 'Point' which is not supported by current database provider. Either change the property CLR type or ignore the property using the '[NotMapped]' attribute or by using 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.

Should this not work?

@dpedrelli Please open a new issue and include a runnable project/solution or complete code listing that demonstrates the behavior you are seeing so that we are better able to investigate it.

@ajcvickers
I created a new solution and it worked as expected. I'll have to do more digging.

Worked with this solution :)

Was this page helpful?
0 / 5 - 0 ratings