Entity Framework Core, исключение NpgSql и Postgis

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

Я установил расширение 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,
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
3
0
1 495
1

Ответы 1

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

Во-первых, убедитесь, что 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);

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

Другие вопросы по теме