Entity Framework Core, исключение NpgSql и Postgis - PullRequest
0 голосов
/ 14 сентября 2018

Я следовал этой документации, чтобы использовать пространственные данные в моем проекте.

Я установил расширение postgis с помощью Stack Builder, создал модель, миграцию, применил ее, и все было хорошо.

Проблема в том, когда я выполняю проект. В первый раз, когда требуется база данных, я получил это исключение:

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

Единственный способ продолжить выполнение проекта - добавить атрибут NoMapping в свойство пространственных данных моей модели:

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; }

    }
}

Внутри метода CreateDbContext я настроен на использование набора топологий следующим образом:

var builder = new DbContextOptionsBuilder<FleetDbContext>();

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

И в OnModelCreating я гарантирую, что расширение postgis присутствует следующим образом:

builder.HasPostgresExtension("postgis");

В базе данных столбец создан правильно.

"Location" "public"."geometry" NOT NULL,

1 Ответ

0 голосов
/ 11 марта 2019

Для меня это работало в одном проекте, но не в другом новом проекте.

Сначала убедитесь, что DbContextOptionsBuilder действительно вызывается.Это было настроено на использование сервера sql в некоторых случаях, postgres в других на основе настроек приложений.

Далее, и это была моя последняя ошибка, мне пришлось внести несколько изменений пакета nuget в свой слой данных:

<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" />

Мне пришлось удалить "Microsoft.EntityFrameworkCore.InMemory "из моего проекта модульного тестирования.

Настройка базы данных:

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

    services.AddSingleton(options);

После этих изменений мои модульные тесты сработали.Код приложения уже работал.Каждая другая область моего кода выглядит идентично тому, что вы добавили.

...