提问人:Tan Nguyen 提问时间:11/11/2021 更新时间:11/25/2021 访问量:843
System.NullReference生成时引发异常 HasForeignKey [已关闭]
System.NullReferenceException throw when build HasForeignKey [closed]
问:
我有这样的代码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)
如何解决此异常
答:
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);
}
评论