System.NullReference生成时引发异常 HasForeignKey [已关闭]

System.NullReferenceException throw when build HasForeignKey [closed]

提问人:Tan Nguyen 提问时间:11/11/2021 更新时间:11/25/2021 访问量:843

问:


编辑问题以包括所需的行为、特定问题或错误以及重现问题所需的最短代码。这将帮助其他人回答这个问题。

1年前关闭。

我有这样的代码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)

如何解决此异常

C# 实体框架 外键 nullreferenceexception

评论

1赞 Caius Jard 11/11/2021
请完整复制代码
0赞 Tan Nguyen 11/11/2021
出于安全原因,我无法发布完整的代码@CaiusJard
0赞 Tan Nguyen 11/11/2021
我想我应该 e.Id 更改为可空。是否正确
2赞 Caius Jard 11/11/2021
哦,我不想要完整的代码,我想要一个完整的复制品——我们可以从字面上粘贴到 VS 中,点击播放并看着它爆炸。随心所欲地调用表和列;person:address 只要您可以重现问题,就会这样做。通过完整复制,我们可以告诉您出了什么问题,或者确认您是否在EF中发现了错误。

答:

1赞 T. Nielsen 11/11/2021 #1

看起来你错过了 .HasPrincipalKey

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

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

0赞 idilov 11/25/2021 #2

两个实体类型之间存在多个一对一关系时,这似乎是一个已知的 bug。

之前打电话为我解决了这个问题。详情请继续阅读:entity.HasOne(d => d.Parent).WithOne(p => 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 });
    });

当我搬家,问题消失了。但是,不应修改生成的代码。我继承了脚手架的 DbContext,并在子类中写了这个:entity.HasOne(d => d.Parent).WithOne(p => p.Child)...entity.HasKey()

    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);
    }