在 Ef Core 中添加对拥有对象的引用

Adding Reference To Owning Object In Ef Core

我在我们的代码优先数据库中有两个实体:Job 和 Orderable:

这两个的(极简)型号是:

class Job 
{
     public Guid Id {get; set;}
     public string JobName {get; set;}
     public List<Orderable> Items {get; set;}
}

class Orderable
{
    public Guid Id {get; set;}
    public string MaterialNumber {get; set;}
}

我希望能够从 orderable 中引用 Job,所以我添加了一个 属性,如下所示:

    public Job OwningObject {get; set;}

但是当我进行迁移时,它为此对象创建了第二个外键。现在,如果我从 Job 中获取 Orderables,它似乎使用 key1,但如果我从 Orderable 获取 Job,它使用 key2。

在上下文中的 OnmodelCreating 方法中,我们在创建密钥之前添加了以下内容,我认为这是使其工作所必需的,但我不确定这是否可能导致问题。

modelBuilder.Entity<Job>().HasMany(x => x.Items).WithOne();

我们能够强制密钥引用具有数据注释的正确字段:

    [ForeignKey("OwningObjectId1")]

但这感觉很老套,我不喜欢将其作为永久解决方案。

EF 在未应用显式外键 属性 时使用影子属性来保持外键关系。 最好要做的就是拥有明确的外键属性:

[ForeignKey(nameof(OwningObject)]
public Guid OwningObjectId { get; set; }
public Job OwningObject { get; set; }

如果你要依赖影子属性,那么你需要仔细考虑你在做什么。

首先,当您使用 WithOne() 时,如果没有参数,它会根据相关实体 Job 创建影子 属性。结果,您将得到一列 JobId。当您有一个引用 属性 时,它将假定一个基于该 属性 名称的外键列:OwningObjectId。本质上,使用 WithOne() 且未在参数中引用 属性 的引用 属性 的组合实际上创建了 two 分离一对多关系。这可以通过简单地告诉 EF 明确使用哪个 属性 来轻松纠正:

modelBuilder.Entity<Job>().HasMany(x => x.Items).WithOne(x => x.OwningObject);