Entity Framework Core, NpgSql and Postgis exception

asp.net-mvc entity-framework-core npgsql postgis postgresql

Question

I followed this documentation to use the spatial data in my project.

I have installed the postgis extension with the Stack Builder, I created the model, the migration, I've applyed it and everything was fine.

The problem is when I execute the project. The first time it require the database, I got this exception:

System.InvalidOperationException
  HResult=0x80131509
  Message=The property 'Point.Boundary' is of an interface type ('IGeometry'). If it is a navigation property manually configure the relationship for this property by casting it to a mapped entity type, otherwise ignore the property using the NotMappedAttribute or 'EntityTypeBuilder.Ignore' in 'OnModelCreating'.
  Source=Microsoft.EntityFrameworkCore
  StackTrace:
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.PropertyMappingValidationConvention.Apply(InternalModelBuilder modelBuilder)
   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelBuilt(InternalModelBuilder modelBuilder)
   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)
   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)
   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)
   at System.Lazy`1.CreateValue()
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)
   at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
   at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
   at Microsoft.EntityFrameworkCore.Internal.InternalAccessorExtensions.GetService[TService](IInfrastructure`1 accessor)
   at Fleet.Data.Infrastructure.DbContextExtensions.EnsureMigrated(FleetDbContext context) in d:\WorkingCopy\fleet\Fleet.Data\Infrastructure\FleetDbContext.cs:line 99
   at Fleet.Startup.Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory) in d:\WorkingCopy\fleet\Fleet\Startup.cs:line 267

The only way to keep executing the project is to add the NoMapping attribute the the spatial data property of my model:

using System;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel.DataAnnotations.Schema;
using NetTopologySuite.Geometries;

namespace Fleet.Data.Models
{

    public enum GpsSources
    {
        Unknown = 0,
        Shift,
        Refuelling,
        Transport,
        Assistance,
        Workshop
    }


    public class Gps
    {

        [Key]
        public int Id { get; set; }


        [Required]
        public virtual Vehicle Vehicle { get; set; }


        [Required]
        [NotMapped]
        public Point Location { get; set; }


        public string Description { get; set; }

        public GpsSources Source { get; set; }

        public int SourceId { get; set; }

        [Required]
        public virtual ApplicationUser User { get; set; }

        public DateTime Date { get; set; }

    }
}

Inside the CreateDbContext method, I set to use the topology suite in this way:

var builder = new DbContextOptionsBuilder<FleetDbContext>();

builder.UseNpgsql(connectionString, o => o.UseNetTopologySuite());

And into the OnModelCreating I ensure the postgis extension is present in this way:

builder.HasPostgresExtension("postgis");

In the database the column was created correctly.

"Location" "public"."geometry" NOT NULL,
1
3
9/14/2018 10:20:06 AM

Popular Answer

For me this worked in one project, but not another new project.

First, make sure DbContextOptionsBuilder is actually being called. This was setup to use sql server in some instance, postgres in others based on appsetting.

Next, and this was my latest error, there were a couple of nuget package changes I had to make to my data layer:

<PackageReference Include="Microsoft.CodeCoverage" Version="1.0.3" />
<PackageReference Include="Microsoft.EntityFrameworkCore.InMemory" Version="2.2.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.SqlServer" Version="2.2.2" />
<PackageReference Include="Microsoft.EntityFrameworkCore.Tools" Version="2.2.2">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
</PackageReference>
<PackageReference Include="NetTopologySuite.IO.GeoJSON" Version="1.15.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL" Version="2.2.0" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.Design" 
Version="1.1.1" />
<PackageReference Include="Npgsql.EntityFrameworkCore.PostgreSQL.NetTopologySuite" 
Version="2.2.0" />
<PackageReference Include="Npgsql.GeoJSON" Version="1.0.0" />
<PackageReference Include="Npgsql.NetTopologySuite" Version="4.0.5" />

I had to remove "Microsoft.EntityFrameworkCore.InMemory" from my unit test project.

Configuring DB:

    var options = new DbContextOptionsBuilder<UserJurisdictionsContext>()
    .UseNpgsql(configuration.GetConnectionString("DbConnection"),
    x => x.UseNetTopologySuite())
        .Options;

    services.AddSingleton(options);

After these changes, my unit tests worked. The app code was already working. Every other area of my code looks identical to what you added.

0
3/11/2019 7:00:02 PM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow