实体框架 6 导航属性别名
本文关键字:属性 别名 导航 框架 实体 | 更新日期: 2023-09-27 18:37:23
我有两个类:
public class Foo
{
[Key]
public int Id { get; set; }
public string Name { get; set; }
// ...
// Foo has N bars, 1 of which is primary
[ForeignKey("Bar")]
public int? PrimaryBarId { get; set; }
public virtual Bar PrimaryBar { get; set; }
}
public class Bar {
[Key]
public int Id { get; set; }
public string Name { get; set; }
// ...
// Foo -> Bar == 1:N
[ForeignKey("Foo")]
public int FooId { get; set; }
public virtual Foo Foo { get; set; }
}
EF 现在希望我创建一个属性BarId
并在Foo
上Bar
,但我不希望这样。我希望将该属性命名为主栏。我对Foo
-> Bar
有 1:N 的关系,这反映在其他地方,对这个问题不感兴趣。
EF 一直告诉我:
The ForeignKeyAttribute on property 'PrimaryBarId' on type 'X.y.Foo' is not valid. The navigation property 'Bar' was not found on the dependent type 'X.y.Foo'. The Name value should be a valid navigation property name.
如何说服 EF 使用 PrimaryBar
(和 PrimaryBarId
)属性(最好是属性,尽管在OnModelCreating
覆盖中使用DbModelBuilder
也是一种选择?
编辑
想通了。我缺少一个:
public virtual ICollection<Bar> Bar { get; set; }
在我的Foo
课上。有关说明,请参阅此处。
根据文档,提供给ForeignKeyAttribute
的Name
应该是属性名称,而不是类型或表名称。因此,请将您的代码更改为:
public int? PrimaryBarId { get; set; }
[ForeignKey("PrimaryBarId")]
public virtual Bar PrimaryBar { get; set; }
或:
[ForeignKey("PrimaryBar")]
public int? PrimaryBarId { get; set; }
public virtual Bar PrimaryBar { get; set; }
首先要做的事。
如果您的 FK 属性是可空的 int,就像我在代码中看到的那样,您的关系将是 0..1-N 而不是 1-N,因为它是一个可为空的外键。
其次,我对属性语法不是很熟悉,因为它不适合描述您的模型,并且它会用 EF 相关数据混淆您的对象。首选方法是在单独的类中声明 EF 映射,该类继承EntityTypeConfiguration<T>
其中T
是你的类。
现在给定你的类,首先你必须在映射 N 引用的Bar
上添加一个属性,如下所示:
public virtual ICollection<Foo> Foos {get;set;}
然后,您可以声明一个EntityTypeConfiguration<Bar>
,除定义主键和属性>列名称转换(如果它们不匹配)等其他设置外,将包含:
this
.HasMany(p => p.Foos)
.WithOptional(p => p.PrimaryBar)
.HasForeignKey(p => p.PrimaryBarId);
如果您的 FK 是 int
而不是 int?
您将使用 WithRequired
而不是 WithOptional
。
根据 MSDN 名称参数不是实体名称,而是导航属性名称(在您的情况下,因为它比这更复杂)。
您应该将代码从:
[ForeignKey("Bar")]
自:
[ForeignKey("PrimaryBar")]
我非常抱歉,但没有一个答案是正确的。也就是说:它们是正确的(可能),但我发布了错误的问题示例代码。首先我忘记重命名某些类型/属性,然后在我发布的错误消息中发现了一个错误。最后,事实证明我忘了在我的Bar
课上发布以下代码:
class Bar {
//Didn't post this code:
[ForeignKey("Foo")]
public int FooId { get; set; }
public virtual Foo Foo { get; set; }
}
此代码适用于 1:N Foo
必须Bar
。但是由于PrimaryBar
属性意味着 1:0..1 的关系 EF 我猜很困惑。我缺少的是我的Foo
类中包含 1:0..N 和 Bar
以下内容:
class Foo {
public virtual ICollection<Bar> Bars { get; set; }
}
我添加了这个集合,瞧;现在一切正常。
哦,我确实不得不将外键更改为PrimaryBar
,而不是像大多数答案建议的那样Bar
。
非常抱歉和过错:所有都是我的,而且只有我自己的。我通常不喜欢发布"Foo/Bar/Baz"代码而不是实际代码,但在这种情况下,这有点困难,类会自己提出(不相关的)问题,我不想讨论:P
我对所有答案都投了赞成票作为"谢谢";但是,由于它们都不是实际的解决方案,再次因为我是一个笨蛋并且发布了不正确的代码/信息,我发布了自己的答案。