npgsql / efcore.pg

Entity Framework Core provider for PostgreSQL
PostgreSQL License
1.54k stars 226 forks source link

Method 'Create' in type 'NetTopologySuiteHandlerFactory' does not have an implementation #1067

Closed rdunn-geoplan closed 5 years ago

rdunn-geoplan commented 5 years ago

Getting this error when trying to run a .Net Core project (v2.2) which connects to a PostgreSQL DB.

I want to use the NetTopologySuite spatial types for some DB table columns e.g. point geometry column.

Any ideas how to fix this? Am I missing a package?

Below is code with comment where error occurs:

using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Design;
using Npgsql;

namespace DbApp
{
    public class RoutingDbContextFactory : IDesignTimeDbContextFactory<RoutingDbContext>
    {
        public RoutingDbContext CreateDbContext(string[] args)
        {
            var settings = new Settings();
            var optionsBuilder = new DbContextOptionsBuilder<RoutingDbContext>();

            // Error when running this line
            optionsBuilder.UseNpgsql(settings.PostgreSqlConnectionString, o => o.UseNetTopologySuite());

            return new RoutingDbContext(optionsBuilder.Options);
        }
    }
}

System.TypeLoadException HResult=0x80131522 Message=Method 'Create' in type 'Npgsql.NetTopologySuite.NetTopologySuiteHandlerFactory' from assembly 'Npgsql.NetTopologySuite, Version=4.0.4.1, Culture=neutral, PublicKeyToken=5d8b90d52f46fda7' does not have an implementation. Source=Npgsql.NetTopologySuite StackTrace: at Npgsql.NpgsqlNetTopologySuiteExtensions.UseNetTopologySuite(INpgsqlTypeMapper mapper, ICoordinateSequenceFactory coordinateSequenceFactory, IPrecisionModel precisionModel, Ordinates handleOrdinates, Boolean geographyAsDefault) in C:\projects\npgsql\src\Npgsql.NetTopologySuite\NpgsqlNetTopologySuiteExtensions.cs:line 83 at Microsoft.EntityFrameworkCore.NpgsqlNetTopologySuiteDbContextOptionsBuilderExtensions.UseNetTopologySuite(NpgsqlDbContextOptionsBuilder optionsBuilder, ICoordinateSequenceFactory coordinateSequenceFactory, IPrecisionModel precisionModel, Ordinates handleOrdinates, Boolean geographyAsDefault) in C:\projects\npgsql-entityframeworkcore-postgresql\src\EFCore.PG.NTS\Extensions\NpgsqlNetTopologySuiteDbContextOptionsBuilderExtensions.cs:line 35 at DbApp.RoutingDbContextFactory.<>c.b__0_0(NpgsqlDbContextOptionsBuilder o) in k:\geoplan\DbApp\DbApp\RoutingDbContextFactory.cs:line 19 at Microsoft.EntityFrameworkCore.NpgsqlDbContextOptionsExtensions.UseNpgsql(DbContextOptionsBuilder optionsBuilder, String connectionString, Action1 npgsqlOptionsAction) in C:\projects\npgsql-entityframeworkcore-postgresql\src\EFCore.PG\Extensions\NpgsqlDbContextOptionsExtensions.cs:line 41 at Microsoft.EntityFrameworkCore.NpgsqlDbContextOptionsExtensions.UseNpgsql[TContext](DbContextOptionsBuilder1 optionsBuilder, String connectionString, Action`1 npgsqlOptionsAction) in C:\projects\npgsql-entityframeworkcore-postgresql\src\EFCore.PG\Extensions\NpgsqlDbContextOptionsExtensions.cs:line 89 at DbApp.RoutingDbContextFactory.CreateDbContext(String[] args) in k:\geoplan\DbApp\DbApp\RoutingDbContextFactory.cs:line 19 at DbApp.Program.Main(String[] args) in k:\geoplan\DbApp\DbApp\Program.cs:line 12

Here's my .csproj file:

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp2.2</TargetFramework>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="GeoAPI.Core" Version="1.7.5" />
    <PackageReference Include="Microsoft.EntityFrameworkCore" Version="2.2.0" />
    <PackageReference Include="Microsoft.EntityFrameworkCore.Relational" Version="2.2.0" />
    <PackageReference Include="Microsoft.Extensions.Configuration.Json" Version="2.2.0" />
    <PackageReference Include="Npgsql" Version="4.1.1" />
    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.2.0" />
    <PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite" Version="2.2.0" />
  </ItemGroup>
  <ItemGroup>
    <None Update="appsettings.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
    <None Update="dbsettings.json">
      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
    </None>
  </ItemGroup>
</Project>
rdunn-geoplan commented 5 years ago

If I install the package Npgsql.NetTopologySuite the code runs further without the above error but then throws the following error:

System.MissingMethodException HResult=0x80131513 Message=Method not found: 'Npgsql.TypeMapping.INpgsqlTypeMapper Npgsql.NpgsqlNetTopologySuiteExtensions.UseNetTopologySuite(Npgsql.TypeMapping.INpgsqlTypeMapper, GeoAPI.Geometries.ICoordinateSequenceFactory, GeoAPI.Geometries.IPrecisionModel, GeoAPI.Geometries.Ordinates, Boolean)'. Source=Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite StackTrace: at Microsoft.EntityFrameworkCore.NpgsqlNetTopologySuiteDbContextOptionsBuilderExtensions.UseNetTopologySuite(NpgsqlDbContextOptionsBuilder optionsBuilder, ICoordinateSequenceFactory coordinateSequenceFactory, IPrecisionModel precisionModel, Ordinates handleOrdinates, Boolean geographyAsDefault) in C:\projects\npgsql-entityframeworkcore-postgresql\src\EFCore.PG.NTS\Extensions\NpgsqlNetTopologySuiteDbContextOptionsBuilderExtensions.cs:line 45 at DbApp.RoutingDbContextFactory.<>c.b__0_0(NpgsqlDbContextOptionsBuilder o) in k:\geoplan\DbApp\DbApp\RoutingDbContextFactory.cs:line 19 at Microsoft.EntityFrameworkCore.NpgsqlDbContextOptionsExtensions.UseNpgsql(DbContextOptionsBuilder optionsBuilder, String connectionString, Action1 npgsqlOptionsAction) in C:\projects\npgsql-entityframeworkcore-postgresql\src\EFCore.PG\Extensions\NpgsqlDbContextOptionsExtensions.cs:line 41 at Microsoft.EntityFrameworkCore.NpgsqlDbContextOptionsExtensions.UseNpgsql[TContext](DbContextOptionsBuilder1 optionsBuilder, String connectionString, Action`1 npgsqlOptionsAction) in C:\projects\npgsql-entityframeworkcore-postgresql\src\EFCore.PG\Extensions\NpgsqlDbContextOptionsExtensions.cs:line 89 at DbApp.RoutingDbContextFactory.CreateDbContext(String[] args) in k:\geoplan\DbApp\DbApp\RoutingDbContextFactory.cs:line 19 at DbApp.Program.Main(String[] args) in k:\geoplan\DbApp\DbApp\Program.cs:line 12

rdunn-geoplan commented 5 years ago

If I upgrade the packages to v2.2.4 it works.

roji commented 5 years ago

Unfortunately you cannot use Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite 4.1.0 with EF Core 2.2, this is documented in the breaking changes notes.

If you're using the spatial plugin EF Core 2.2 will only work with Npgsql 4.0, and EF Core 3.0 will only work with Npgsql 4.1 (this is due to a major change in NetTopologySuite itself). People not using the NetTopologySuite should be able to mix versions.

rdunn-geoplan commented 5 years ago

@roji If I'm referencing another assembly which also uses NTS, can you advise what version of NTS to use in the referenced assembly in order to ensure compatibility with Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite?

I don't see any version 4.1.0 available from Nuget, the latest version for NetTopologySuite is v2.0.0 and NetTopologySuite.Core is v1.15.3

rdunn-geoplan commented 5 years ago

I'm getting this error:

System.TypeLoadException: Could not load type 'GeoAPI.NetTopologySuiteBootstrapper' from assembly 'NetTopologySuite, Version=2.0.0.0, Culture=neutral, PublicKeyToken=f580a05016ebada1'. at Npgsql.NpgsqlNetTopologySuiteExtensions.UseNetTopologySuite(INpgsqlTypeMapper mapper, ICoordinateSequenceFactory coordinateSequenceFactory, IPrecisionModel precisionModel, Ordinates handleOrdinates, Boolean geographyAsDefault) at Microsoft.EntityFrameworkCore.NpgsqlNetTopologySuiteDbContextOptionsBuilderExtensions.UseNetTopologySuite(NpgsqlDbContextOptionsBuilder optionsBuilder, ICoordinateSequenceFactory coordinateSequenceFactory, IPrecisionModel precisionModel, Ordinates handleOrdinates, Boolean geographyAsDefault) in C:\projects\npgsql-entityframeworkcore-postgresql\src\EFCore.PG.NTS\Extensions\NpgsqlNetTopologySuiteDbContextOptionsBuilderExtensions.cs:line 35