【问题标题】:System.NullReferenceException throw when build HasForeignKey [closed]构建 HasForeignKey 时抛出 System.NullReferenceException [关闭]
【发布时间】:2021-11-11 08:15:40
【问题描述】:

我有这样的代码 c#

    builder.Entity<EnPpTime>()
         .HasOne(a => a.EnPpTimeInMeta).WithOne(b => b.EnPpTime)
         .HasForeignKey<EnPpTimeInMeta>(e => e.Id);

程序运行时抛出异常

System.NullReferenceException: Object reference not set to an instance of an object.
[2021-11-11T07:06:30.667Z]    at Microsoft.EntityFrameworkCore.Metadata.Conventions.ForeignKeyAttributeConvention.UpdateRelationshipBuilder(IConventionForeignKeyBuilder relationshipBuilder, IConventionContext context)
[2021-11-11T07:06:30.668Z]    at Microsoft.EntityFrameworkCore.Metadata.Conventions.ForeignKeyAttributeConvention.ProcessForeignKeyAdded(IConventionForeignKeyBuilder relationshipBuilder, IConventionContext`1 context)
[2021-11-11T07:06:30.668Z]    at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ImmediateConventionScope.OnForeignKeyAdded(IConventionForeignKeyBuilder relationshipBuilder)
[2021-11-11T07:06:30.669Z]    at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.OnForeignKeyAddedNode.Run(ConventionDispatcher dispatcher)
[2021-11-11T07:06:30.669Z]    at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.DelayedConventionScope.Run(ConventionDispatcher dispatcher)
[2021-11-11T07:06:30.670Z]    at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ConventionBatch.Run()
[2021-11-11T07:06:30.670Z]    at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionDispatcher.ConventionBatch.Run(IConventionForeignKey foreignKey)
[2021-11-11T07:06:30.671Z]    at Microsoft.EntityFrameworkCore.Metadata.Conventions.Internal.ConventionBatchExtensions.Run(IConventionBatch batch, InternalForeignKeyBuilder relationshipBuilder)
[2021-11-11T07:06:30.671Z]    at Microsoft.EntityFrameworkCore.Metadata.Builders.ReferenceReferenceBuilder.HasForeignKeyBuilder(EntityType dependentEntityType, String dependentEntityTypeName, Func`3 hasForeignKey)
[2021-11-11T07:06:30.672Z]    at Microsoft.EntityFrameworkCore.Metadata.Builders.ReferenceReferenceBuilder.HasForeignKeyBuilder(EntityType dependentEntityType, String dependentEntityTypeName, IReadOnlyList`1 foreignKeyMembers)
[2021-11-11T07:06:30.672Z]    at Microsoft.EntityFrameworkCore.Metadata.Builders.ReferenceReferenceBuilder`2.HasForeignKey[TDependentEntity](Expression`1 foreignKeyExpression)

如何解决这个异常

【问题讨论】:

  • 请完整复制代码
  • 出于安全原因,我无法发布完整代码@CaiusJard
  • 我认为我应该将 e.Id 更改为可为空。是否正确
  • 哦,我不想要完整的代码,我想要一个完整的复制品——这是我们可以直接粘贴到 VS 中的代码,点击 Play 并观看它的运行。随意调用表格和列;只要您可以重现问题,person:address 就可以。通过完整的复制,我们可以告诉您出了什么问题,或者确认您是否在 EF 中发现了错误。

标签: c# entity-framework foreign-keys nullreferenceexception


【解决方案1】:

看起来你错过了 .HasPrincipalKey

在这种情况下,它将默认在您的情况“EnPpTimeID”中查找实体名称后缀“ID”,如果它不存在则会失败

在使用实体框架时始终使用 EntityTypeNameID 作为标识列是一个非常好的主意,在这种情况下,您不必显式定义外键和主键

【讨论】:

    【解决方案2】:

    当有multiple one-to-one relationships between two entity types 时,这似乎是一个已知错误。

    致电entity.HasOne(d =&gt; d.Parent).WithOne(p =&gt; p.Child) 之前 entity.HasKey() 为我解决了这个问题。请继续阅读以了解详细信息:

    我在使用 EF core 5 时遇到了同样的问题 - .HasForeignKey() 抛出了上述异常。 DbContext 是脚手架。脚手架不会为单列外键生成 .HasPrincipalKey()。手动添加 .HasPrincipalKey() 并没有解决问题。然而,我的表有两个 1:1 的关系。这意味着子表有 4 个约束:两个外键和两个唯一键位于与 FK 相同的列上。脚手架代码是:

        builder.Entity<Child>(entity =>
        {
            // 2 unique keys.
            entity.HasKey(e => e.ParentId);
            entity.HasIndex(e => new { e.OtherId, e.ParentId }).IsUnique();
            entity.Property(e => e.ParentId).ValueGeneratedNever();
    
            // 2 foreign keys.
            entity.HasOne(d => d.Parent).WithOne(p => p.Child)
                .HasForeignKey<Child>(d => d.ParentId);  // <---- Throws exception!
            entity.HasOne(d => d.Parent2).WithOne(p => p.Child2)
                .HasPrincipalKey<Parent>(p => new { p.OtherId, p.Id })
                .HasForeignKey<Child>(d => new { d.OtherId, d.ParentId });
        });
    

    当我移动entity.HasOne(d =&gt; d.Parent).WithOne(p =&gt; p.Child)... 之前 entity.HasKey() 时问题消失了。但是,您不应修改生成的代码。我继承了脚手架的 DbContext 并在子类中写道:

        protected override void OnModelCreating(ModelBuilder builder)
        {
            // Bugfix:
            builder.Entity<Child>().HasOne(d => d.Parent).WithOne(p => p.Child);
            // You don't even need .HasForeignKey() here. It will be called inside base.OnModelCreating(). Duplicating .HasOne() and .WithOne() works fine.
            base.OnModelCreating(builder);
        }
    

    【讨论】:

      猜你喜欢
      • 2016-08-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-11-24
      • 2014-11-11
      • 1970-01-01
      相关资源
      最近更新 更多