Я определяю составной первичный ключ с помощью Fluent API, но когда я выполняю код, я получаю сообщение об ошибке, сообщающее, что требуется первичный ключ - PullRequest
0 голосов
/ 11 июля 2019

Я не уверен, что изменилось, но теперь я получаю сообщение об ошибке: " Тип сущности 'GroupSubscriber' требует определения первичного ключа. " Однако у меня определен составной ключ в конфигурации EF, которую я подтвердил, действительно выполняется. Кроме того, я могу создать миграцию и обновить базу данных, в результате чего БД имеет составной первичный ключ.

Проект веб-API успешно собирается и может работать, но когда я вызываю любой маршрут, я получаю эту ошибку, даже если у меня вообще нет доступа к этому объекту.

Как я уже говорил, все это прекрасно работает, но кажется, что когда я вызываю маршрут для чего-то не связанного, это дает мне эту ошибку. Странно то, что я получаю и другие ошибки с .HasConversion, который раньше работал, но теперь сделал. Я преодолел эти ошибки с помощью обходных путей, но не могу сделать обходной путь для составного ключа, так как не могу изменить схему БД.

Если вам интересно, вот полная ошибка, которую я получаю:

{
    "error": [
        "The entity type 'GroupSubscriber' requires a primary key to be defined."
    ],
    "stackTrace": "   at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.ValidateNonNullPrimaryKeys(IModel model)\r\n   at Microsoft.EntityFrameworkCore.Infrastructure.ModelValidator.Validate(IModel model)\r\n   at Microsoft.EntityFrameworkCore.Infrastructure.RelationalModelValidator.Validate(IModel model)\r\n   at Microsoft.EntityFrameworkCore.Internal.SqlServerModelValidator.Validate(IModel model)\r\n   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ValidatingConvention.Apply(InternalModelBuilder modelBuilder)\r\n   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnModelBuilt(InternalModelBuilder modelBuilder)\r\n   at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnModelBuilt(InternalModelBuilder modelBuilder)\r\n   at Microsoft.EntityFrameworkCore.Metadata.Internal.Model.Validate()\r\n   at Microsoft.EntityFrameworkCore.ModelBuilder.FinalizeModel()\r\n   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)\r\n   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.<>c__DisplayClass5_0.<GetModel>b__1()\r\n   at System.Lazy`1.ViaFactory(LazyThreadSafetyMode mode)\r\n   at System.Lazy`1.ExecutionAndPublication(LazyHelper executionAndPublication, Boolean useDefaultConstructor)\r\n   at System.Lazy`1.CreateValue()\r\n   at Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder, IModelValidator validator)\r\n   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()\r\n   at Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()\r\n   at Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder.<>c.<TryAddCoreServices>b__7_2(IServiceProvider p)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, ServiceProviderEngineScope scope)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, ServiceProviderEngineScope scope)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScoped(ScopedCallSite scopedCallSite, ServiceProviderEngineScope scope)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor`2.VisitCallSite(IServiceCallSite callSite, TArgument argument)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine.<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)\r\n   at Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService[T](IServiceProvider provider)\r\n   at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()\r\n   at Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()\r\n   at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()\r\n   at Microsoft.EntityFrameworkCore.DbContext.get_Model()\r\n   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityType()\r\n   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.get_EntityQueryable()\r\n   at Microsoft.EntityFrameworkCore.Internal.InternalDbSet`1.System.Linq.IQueryable.get_Provider()\r\n   at System.Linq.Queryable.Where[TSource](IQueryable`1 source, Expression`1 predicate)\r\n   at Application.Accounts.Queries.GetAll.GetAllAccountsQueryHandler.Handle(GetAllAccountsQuery request, CancellationToken cancellationToken) in C:\\Repos\\API\\Application\\Accounts\\Queries\\GetAll\\GetAllAccountsQueryHandler.cs:line 27\r\n   at MediatR.Pipeline.RequestPostProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)\r\n   at MediatR.Pipeline.RequestPreProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)\r\n   at m25.Application.Infrastructure.RequestPerformanceBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next) in C:\\Repos\\API\\Application\\Infrastructure\\RequestPerformanceBehavior.cs:line 25\r\n   at MediatR.Pipeline.RequestPreProcessorBehavior`2.Handle(TRequest request, CancellationToken cancellationToken, RequestHandlerDelegate`1 next)\r\n   at WebApi.Controllers.AccountsController.Get() in C:\\Repos\\API\\WebApi\\Controllers\\AccountsController.cs:line 34\r\n   at lambda_method(Closure , Object )\r\n   at Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()\r\n   at Microsoft.AspNetCore.Mvc.Internal.ActionMethodExecutor.AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, Object controller, Object[] arguments)\r\n   at System.Threading.Tasks.ValueTask`1.get_Result()\r\n   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeActionMethodAsync()\r\n   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeNextActionFilterAsync()\r\n   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Rethrow(ActionExecutedContext context)\r\n   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.Next(State& next, Scope& scope, Object& state, Boolean& isCompleted)\r\n   at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.InvokeInnerFilterAsync()\r\n   at Microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextExceptionFilterAsync()"
}

Я попытался переместить конфигурацию в функцию OnModelCreating вместо того, чтобы использовать отдельный класс, но безуспешно.

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

В случае, если это помогает, другие ошибки, с которыми я сталкивался, заключались в использовании HasConversion для преобразования ICollection в / из CSV, что также вызывало ошибки, но я обработал это в классе (боль, но работоспособна).

GroupSubscriber.cs

public class GroupSubscriber
{
    public Guid SubscriberId { get; set; }
    public Subscriber.Subscriber Subscriber { get; set; }
    public Guid GroupId { get; set; }
    public Group Group { get; set; }
    public long ShardKey { get; set; }
    public Guid AccountId { get; set; }
}

GroupSubscriberConfiguration.cs

public class GroupSubscriberConfiguration : IEntityTypeConfiguration<GroupSubscriber>
{
    public void Configure(EntityTypeBuilder<GroupSubscriber> builder)
    {
        builder.ToTable("SubscriberList_Group_Subscriber");
        builder.HasKey(gs => new { gs.GroupId, gs.SubscriberId });
        builder.Property(e => e.ShardKey).IsRequired();

        builder.HasOne(e => e.Subscriber)
            .WithMany(s => s.GroupSubscribers)
            .HasForeignKey(e => e.SubscriberId)
                .HasConstraintName("FK_SubscriberListGroupSubscriber_Subscriber")
                .OnDelete(DeleteBehavior.ClientSetNull);

        builder.HasOne(e => e.Group)
            .WithMany(g => g.GroupSubscribers)
            .HasForeignKey(e => e.GroupId)
                .HasConstraintName("FK_SubscriberListGroupSubscriber_Group");
    }
}

DbContext.cs

//standard DB Context code above but here's the important part
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder.ApplyConfigurationsFromAssembly(typeof(DbContext).Assembly));
}

Я ожидаю, что смогу использовать Fluent API для настройки составного первичного ключа.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...