【发布时间】:2019-12-30 13:11:08
【问题描述】:
让我们从一对多关系开始:
public sealed class MyContext : DbContext
{
protected override void OnModelCreating(ModelBuilder builder)
{
builder.Entity<Slave>()
.HasOne(typeof(Master))
.WithMany() // *
.HasForeignKey(nameof(Slave.ForeignField));
}
}
所以我声明主表中的每一条记录我可以在从表中拥有多条记录。当我运行 EF 工具来构建迁移时,这被接受并且工作正常。
但是当我将标有星号的行更改为:
.WithOne()
为了建立一对一的关系,迁移失败并出现错误:
您正在配置 'Slave' 和 'Master' 之间的关系,但是 在“ForeignField”上指定了一个外键。外键必须 在属于关系一部分的类型上定义。
我不明白,就在一秒钟前,给定的字段(C# 术语中的属性)还可以,现在 EF 声称找不到它?
我错过了什么?如何让EF开心?
记录类型如下——请注意有没有导航属性。
internal sealed class Slave
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid InstanceId { get; set; }
public Guid ForeignField { get; set; }
}
internal sealed class Master
{
[Key]
[DatabaseGenerated(DatabaseGeneratedOption.None)]
public Guid Id { get; set; }
}
目前我使用原始 SQL 解决了这个问题,它可以工作,但我仍然很好奇这里出了什么问题。
感谢@AminGolmahalle 的回答,我的好奇心被触发了为什么以及我可以以通用形式使用HasForeignKey。这让我发现我不能,但更重要的是 WithOne 和 WithMany 不是 1:1 的替代品。两者都会导致不同的重载。
所以第一个版本的一对多工作,因为我遇到了正确的重载,第二个没有,因为我传递了不正确的参数。正确的版本是:
builder.Entity<Slave>()
.HasOne(typeof(Master))
.WithOne()
.HasForeignKey(nameof(Slave), nameof(Slave.ForeignField)); // changed
第一个参数必须是从表的名称(再次)。
但是最好切换到通用版本(请参阅已接受答案下的最后一条评论)并首先避免出现这种“愚蠢”错误的可能性。
【问题讨论】:
标签: c# entity-framework-core one-to-one