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

时间:2019-03-22 14:22:16

标签: asp.net-core orm ef-core-2.1

在我们的代码优先数据库中,我有两个实体: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;}
}

我希望能够从可订购对象中引用作业,因此我添加了如下属性:

    public Job OwningObject {get; set;}

但是当我进行迁移时,它为该对象创建了第二个外键。现在,看来,如果我要从Job那里获取可订购商品,则使用key1,但是如果我要从Orderable那里获取Job,则它将使用key2。

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

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

我们能够使用以下数据注释强制键引用正确的字段:

    [ForeignKey("OwningObjectId1")]

但这感觉很棘手,我不喜欢它作为永久解决方案。

1 个答案:

答案 0 :(得分:1)

在未应用任何显式外键属性的情况下,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);