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

问题描述

您好,我使用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生成,我保持不变。但是,从上下文中使用其他与这两个表无关的表时,会遇到此错误

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,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,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,TResult>.VisitCallSite(ServiceCallSite callSite,TArgument argument)
Microsoft.Extensions.DependencyInjection.ServiceLookup.CallSiteRuntimeResolver.VisitConstructor(ConstructorCallSite constructorCallSite,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,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"))
            );

Debug显示程序在运行Context构造函数和Entity builder ==>时卡住了,因此它甚至没有到达Where()表达式,所以添加Where(..)之后无法解决

EF Core有什么问题?我坚持了这么长时间。

解决方法

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

,

补充答案...

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

enter image description here

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

enter image description here

HasNoKey 已包含在脚手架流程中,因为它没有在我的“部门”表中标识“主键”字段

enter image description here