NetTopologySuite / NetTopologySuite.IO.GeoJSON

GeoJSON IO module for NTS.
BSD 3-Clause "New" or "Revised" License
111 stars 46 forks source link

[Question/Bug] NetTopologySuite.IO.GeoJson in combination with EntityFrameworkCore.SqlServer.NetTopologySuite #38

Closed patrickhacens closed 5 years ago

patrickhacens commented 5 years ago

I'm trying to use SQLServer to search and process geographical data in the backend side and need to import some data from GeoJSON. when including both libs NetTopologySuite.IO.GeoJson 1.7.5 and EntityFrameworkCore.SqlServer.NetTopologySuite 2.2.6 the following error appear when trying to resolve the DbContext

System.MissingMethodException: 'Method not found: 'GeoAPI.IGeometryServices NetTopologySuite.NtsGeometryServices.get_Instance()'.'

after thinkering a bit with it and searching what that issue might be I found out that the problem occurs when one dependency is installed on the project that being NetTopologySuite

Is there a way to make them work together?

<ItemGroup>
    <PackageReference Include = "GeoAPI" Version="1.7.5" />
    <PackageReference Include = "Microsoft.EntityFrameworkCore" Version="2.2.6" />
    <PackageReference Include = "Microsoft.EntityFrameworkCore.SqlServer.NetTopologySuite" Version="2.2.6" />
    <PackageReference Include = "NetTopologySuite.Core" Version="1.15.3" />
    <PackageReference Include = "NetTopologySuite" Version="2.0.0" /> //<-- adding this package will result in the exception being thrown
</ItemGroup>
using GeoAPI.Geometries;
using Microsoft.EntityFrameworkCore;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using System;

namespace script
{
    class Program
    {
        public static string connectionString = "Data Source=(localdb)\\MSSQLLocalDB;Initial Catalog=[database]; Integrated Security=True;";

        public static IConfigurationRoot Configuration { get; private set; }

        static void Main(string[] args)
        {
            IServiceProvider provider = ConfigureServices(new ServiceCollection());

            var x = provider.GetService<Db>(); //will throw exception when NetTopologySuite is added to the project
        }

        public static IServiceProvider ConfigureServices(IServiceCollection services)
        {
            services.AddSingleton<Db>(_ => new Db(new DbContextOptionsBuilder().UseSqlServer(connectionString, x => x.UseNetTopologySuite()).Options));
            services.AddSingleton<IGeometryFactory>(_ => GeoAPI.GeometryServiceProvider.Instance.CreateGeometryFactory(4326));

            return services.BuildServiceProvider();
        }
    }

    public class GeoRecord
    {
        public Guid Id { get; set; }

        public IGeometry Geometry { get; set; }
    }

    public class Db : DbContext
    {
        public Db(DbContextOptions options) : base(options) //exception will be thrown here when trying to resolve Db dependency
        {
        }

        public DbSet<GeoRecord> GeoRecords { get; set; }
    }
}
airbreather commented 5 years ago

Is there a way to make them work together?

Looking at your ItemGroup, I'd say the easiest thing to do is to just drop the NetTopologySuite package reference altogether. When you go to upgrade, make sure to keep the above bullet points in mind.

Sorry about the lack of documentation right around now to help smooth over the 1.x-to-2.x transition...

patrickhacens commented 5 years ago

Thanks for the fast reply I updated the project to use the EF Core 3.x and everything worked as expected