我正在使用Fluent API定义复合主键,但是当我执行代码时,出现错误提示我需要主键

时间:2019-07-11 18:06:24

标签: c# ef-fluent-api

我不确定发生了什么变化,但是现在我收到一条错误消息:“ 实体类型'GroupSubscriber'需要定义主键。”但是,我确实有一个复合键在EF配置中定义,我已确认确实执行。此外,我能够创建迁移并更新数据库,这将导致数据库具有复合主键。

Web 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,或从CSV转换为ICollection,这也引起了错误,但我在类中进行了处理(疼痛但可行)。

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配置复合主键。

0 个答案:

没有答案