在我们的代码优先数据库中,我有两个实体: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")]
但这感觉很棘手,我不喜欢它作为永久解决方案。
答案 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);