PostGis + EF + NetTopologySuite exception writing derived type to db

180 Views Asked by At

I am working on a NET 8 app using EF to connect to a Postgres/PostGis database. I have an entity that has a Geometry? datatype (which is the base of Polygon and Point) where I will store either of the derived types. We have an event driven domain, so I actually wrote a projection to persist the existing events into the database, and all this works fine. I can store both polygons and point with no issue.

I am now working on writing tests for the application level logic. I am using Testcontainers.Postgres to run the postgis/postgis:latest image with the postgis and hstore extensions installed. The test using the same DbContext as the projections. However, when my test attempts to create a new record, I get an exception when saving changes to the db. In the case of storing a Polygon type in the Geometry? property, the exception is

System.InvalidCastException : Writing values of 'NetTopologySuite.Geometries.Polygon' is not supported for parameters having NpgsqlDbType 'Geometry'.

When I try to store a new record with a null Geometry? value, I still get this exception:

System.InvalidCastException : Writing is not supported for parameters having NpgsqlDbType 'Geometry'.

So I know the database is set correctly and the DbContext/EF is configured correctly as the projection has no issue. The biggest unknown in the Testcontainer Postgres instance I'm using. But that's running the same image that I run the projection on. I can't figure out what to check now. Any ideas?

1

There are 1 best solutions below

2
Sam On BEST ANSWER

There was apparently a change to the way the connetions/type registration works in NpqSql 7. So if you're running 7 or 8, this can happen. It's suggested to use their new NpgsqlDataSourceBuilder. This fixed the issue for me:

 var dataSourceBuilder = new NpgsqlDataSourceBuilder(database.GetConnectionString());
 dataSourceBuilder.UseNetTopologySuite();
 var dataSource = dataSourceBuilder.Build();

 services.AddDbContext<ApplicationDbContext>(options =>
 {
     options.UseNpgsql(dataSource, o =>
     {
         o.MigrationsAssembly(typeof(ApplicationDbContext).Assembly.FullName);
         o.MigrationsHistoryTable(schemaService.MigrationsTableName, schemaService.Name);
         o.UseNetTopologySuite();
     });
 });