Entity Framework 具有外键约束的脚手架实体的核心问题

Entity Framework Core Problem with Scaffolding entity with foreign key constraint

您好,我使用 EF Core 从现有数据库构建 DbContext。结果上下文包含 OnModelCreating(..) 中的 2 个相关实体,如下所示:

modelBuilder.Entity<MauYdc>(entity =>
            {
                entity.HasNoKey();

                entity.ToTable("MauYDC");

                entity.HasIndex(e => e.Idphieu)
                    .HasName("IX_MauYDC")
                    .IsUnique();

                entity.Property(e => e.Idphieu)
                    .HasColumnName("IDphieu")
                    .HasColumnType("numeric(18, 0)")
                    .ValueGeneratedOnAdd();

                entity.Property(e => e.Manv).HasMaxLength(50);

                entity.Property(e => e.Tenphieu)
                    .HasColumnName("tenphieu")
                    .HasMaxLength(100);
            });

modelBuilder.Entity<MauYdcChiTiet>(entity =>
            {
                entity.HasNoKey();

                entity.ToTable("MauYDC_ChiTiet");

                entity.Property(e => e.Id)
                    .HasColumnName("ID")
                    .HasColumnType("numeric(18, 0)")
                    .ValueGeneratedOnAdd();

                entity.Property(e => e.Idphieu)
                    .HasColumnName("IDphieu")
                    .HasColumnType("numeric(18, 0)");

                entity.Property(e => e.Idthuoc).HasColumnName("idthuoc");

                entity.Property(e => e.Soluong).HasColumnName("soluong");

                entity.HasOne(d => d.IdphieuNavigation)
                    .WithMany()
                    .HasPrincipalKey(p => p.Idphieu)
                    .HasForeignKey(d => d.Idphieu)
                    .OnDelete(DeleteBehavior.Cascade)
                    .HasConstraintName("FK_MauYDC_chitiet_MauYDC");
            });

实体MauYdc

public partial class MauYdc
    {
        public decimal Idphieu { get; set; }
        public string Tenphieu { get; set; }
        public string Manv { get; set; }
    }

实体MauYdcChiTiet

public partial class MauYdcChiTiet
    {
        public decimal? Idphieu { get; set; }
        public int? Idthuoc { get; set; }
        public double? Soluong { get; set; }
        public decimal Id { get; set; }

        public virtual MauYdc IdphieuNavigation { get; set; }
    }

这些完全由 EF Core 生成,我保持不变。但是,在与这两个

无关的上下文中使用其他 table 时,我遇到了这个错误
NullReferenceException: Object reference not set to an instance of an object.
Microsoft.EntityFrameworkCore.Metadata.Internal.InternalEntityTypeBuilder.SetOrAddForeignKey(ForeignKey foreignKey, InternalEntityTypeBuilder principalEntityTypeBuilder, IReadOnlyList<Property> dependentProperties, Key principalKey, string navigationToPrincipalName, Nullable<bool> isRequired, Nullable<ConfigurationSource> configurationSource)
Microsoft.EntityFrameworkCore.Metadata.Internal.InternalEntityTypeBuilder.CreateForeignKey(InternalEntityTypeBuilder principalEntityTypeBuilder, IReadOnlyList<Property> dependentProperties, Key principalKey, string navigationToPrincipalName, Nullable<bool> isRequired, ConfigurationSource configurationSource)
Microsoft.EntityFrameworkCore.Metadata.Internal.InternalEntityTypeBuilder.HasRelationship(EntityType targetEntityType, Nullable<MemberIdentity> navigationToTarget, Nullable<MemberIdentity> inverseNavigation, bool setTargetAsPrincipal, ConfigurationSource configurationSource, Nullable<bool> required)
Microsoft.EntityFrameworkCore.Metadata.Internal.InternalEntityTypeBuilder.HasRelationship(EntityType targetEntityType, MemberInfo navigationProperty, ConfigurationSource configurationSource, bool setTargetAsPrincipal)
Microsoft.EntityFrameworkCore.Metadata.Builders.EntityTypeBuilder<TEntity>.HasOne<TRelatedEntity>(Expression<Func<TEntity, TRelatedEntity>> navigationExpression)
Hl7Map.Infrastructure.SqlServer.NgoaiTru.NgoaiTruContext+<>c.<OnModelCreating>b__322_31(EntityTypeBuilder<MauYdcChiTiet> entity) in NgoaiTruContext.cs
+
                entity.HasOne(d => d.IdphieuNavigation)
Microsoft.EntityFrameworkCore.ModelBuilder.Entity<TEntity>(Action<EntityTypeBuilder<TEntity>> buildAction)
Hl7Map.Infrastructure.SqlServer.NgoaiTru.NgoaiTruContext.OnModelCreating(ModelBuilder modelBuilder) in NgoaiTruContext.cs
+
            modelBuilder.Entity<MauYdcChiTiet>(entity =>
Microsoft.EntityFrameworkCore.Infrastructure.ModelCustomizer.Customize(ModelBuilder modelBuilder, DbContext context)
Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.CreateModel(DbContext context, IConventionSetBuilder conventionSetBuilder)
Microsoft.EntityFrameworkCore.Infrastructure.ModelSource.GetModel(DbContext context, IConventionSetBuilder conventionSetBuilder)
Microsoft.EntityFrameworkCore.Internal.DbContextServices.CreateModel()
Microsoft.EntityFrameworkCore.Internal.DbContextServices.get_Model()
Microsoft.EntityFrameworkCore.Infrastructure.EntityFrameworkServicesBuilder+<>c.<TryAddCoreServices>b__7_3(IServiceProvider p)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitFactory(FactoryCallSite factoryCallSite, RuntimeResolverContext context)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<TArgument, TResult>.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<TArgument, TResult>.VisitCallSite(ServiceCallSite callSite, TArgument argument)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite, RuntimeResolverContext context)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<TArgument, TResult>.VisitCallSiteMain(ServiceCallSite callSite, TArgument argument)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitCache(ServiceCallSite callSite, RuntimeResolverContext context, ServiceProviderEngineScope serviceProviderEngine, RuntimeResolverLock lockType)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitScopeCache(ServiceCallSite singletonCallSite, RuntimeResolverContext context)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteVisitor<TArgument, TResult>.VisitCallSite(ServiceCallSite callSite, TArgument argument)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.Resolve(ServiceCallSite callSite, ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.DynamicServiceProviderEngine+<>c__DisplayClass1_0.<RealizeService>b__0(ServiceProviderEngineScope scope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngine.GetService(Type serviceType, ServiceProviderEngineScope serviceProviderEngineScope)
Microsoft.Extensions.DependencyInjection.ServiceLookup.ServiceProviderEngineScope.GetService(Type serviceType)
Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService(IServiceProvider provider, Type serviceType)
Microsoft.Extensions.DependencyInjection.ServiceProviderServiceExtensions.GetRequiredService<T>(IServiceProvider provider)
Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
Microsoft.EntityFrameworkCore.DbContext.get_InternalServiceProvider()
Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
Microsoft.EntityFrameworkCore.DbContext.get_Model()
Microsoft.EntityFrameworkCore.Internal.InternalDbSet<TEntity>.get_EntityType()
Microsoft.EntityFrameworkCore.Internal.InternalDbSet<TEntity>.CheckState()
Microsoft.EntityFrameworkCore.Internal.InternalDbSet<TEntity>.get_EntityQueryable()
Microsoft.EntityFrameworkCore.Internal.InternalDbSet<TEntity>.System.Linq.IQueryable.get_Provider()
System.Linq.Queryable.Where<TSource>(IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate)
Hl7Map.Manager.Administration.PatientManager.Get(string IdBenhNhan) in PatientManager.cs
+
            var tttn= _myContext.MyOtherTable.Where(ttTiepnhan => ttTiepnhan.MaBn == IdBenhNhan)?.FirstOrDefault();
Hl7Map.Areas.FHIR.Controllers.PatientsController.Get(string idBn) in PatientsController.cs
+
            var pt = await _patientManager.Get(idBn);
lambda_method(Closure , object )
Microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable+Awaiter.GetResult()
Microsoft.AspNetCore.Mvc.Infrastructure.ActionMethodExecutor+AwaitableObjectResultExecutor.Execute(IActionResultTypeMapper mapper, ObjectMethodExecutor executor, object controller, object[] arguments)
System.Threading.Tasks.ValueTask<TResult>.get_Result()
System.Runtime.CompilerServices.ValueTaskAwaiter<TResult>.GetResult()
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeActionMethodAsync>g__Awaited|12_0(ControllerActionInvoker invoker, ValueTask<IActionResult> actionResultValueTask)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.<InvokeNextActionFilterAsync>g__Awaited|10_0(ControllerActionInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Rethrow(ActionExecutedContextSealed context)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.Next(ref State next, ref Scope scope, ref object state, ref bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ControllerActionInvoker.InvokeInnerFilterAsync()
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeFilterPipelineAsync>g__Awaited|19_0(ResourceInvoker invoker, Task lastTask, State next, Scope scope, object state, bool isCompleted)
Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.<InvokeAsync>g__Awaited|17_0(ResourceInvoker invoker, Task task, IDisposable scope)
Microsoft.AspNetCore.Routing.EndpointMiddleware.<Invoke>g__AwaitRequestTask|6_0(Endpoint endpoint, Task requestTask, ILogger logger)
Microsoft.AspNetCore.Authorization.AuthorizationMiddleware.Invoke(HttpContext context)
Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(HttpContext context)

我已经为 EF Core 使用延迟加载:

services.AddDbContext<MyContext>(options =>
                options.UseLazyLoadingProxies().UseSqlServer(config.GetConnectionString("MyConnectionString"))
            );

调试显示程序在 运行 上下文构造函数和实体生成器 ==> 时卡住了,所以它甚至没有到达 Where() 表达式,所以添加 ? Where(..) 之后无法修复。

EF Core 有什么问题?我被困了这么久。

在尝试使其与现有数据库一起工作 => 失败后,唯一的解决方案是将键添加到两个表(主表和引用表)以使 EF Core 正常运行。 EF 不允许对无键表进行外键约束。

补充答案...

实际上,发生此错误是因为实体被定义为“无键”

因此,初始化上下文时,在定义关系时会产生错误...

HasNoKey 包含在脚手架进程中,因为它没有在我的 'Departamento' table

中识别主键字段