Entity Framework 6 导航 属性 别名?
Entity Framework 6 Navigation property alias?
我有这两个 classes:
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 现在希望我在 Foo
上创建 属性 BarId
和 Bar
,但我不希望那样。我希望将 属性 命名为 PrimaryBar。我在 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
class 上。参见 的解释。
要事第一。
如果你的 FK 属性 是一个可以为 null 的整数,就像我在你的代码中看到的那样,你的关系将是 0..1-N 而不是 1-N,因为它是一个可以为 null 的外键。
其次,我对属性语法不是很熟悉,因为它不适合描述您的模型,并且它会使您的对象与 EF 相关数据混淆。首选方法是在继承 EntityTypeConfiguration<T>
的单独 class 中声明 EF 映射,其中 T
是您的 class.
现在给定您的 classes,首先您必须在 Bar
上添加一个 属性 来映射 N 引用,如下所示:
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")]
根据 the documentation,提供给 ForeignKeyAttribute
的 Name
应该是 属性 名称,而不是类型或 table 名称。因此,将您的代码更改为:
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; }
非常抱歉,但 none 的答案是正确的。也就是说:他们 是 正确的(可能),但我 post 编辑了我的示例代码以解决问题。首先我忘记重命名一些 types/properties,然后我在 post 编辑的错误消息中发现了一个错误。最后我发现我忘了 post 我在 Bar
class:
上的以下代码
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
class 上包含 1:0..N 和 Bar
:
的以下内容
class Foo {
public virtual ICollection<Bar> Bars { get; set; }
}
我添加了这个合集等等;现在一切正常。
哦,我 确实 必须将 ForeignKey 更改为 PrimaryBar
而不是 Bar
确实如大多数答案所建议的那样。
我非常抱歉和我的过失:所有他妈的都是我的,而且只是我自己的。我通常不喜欢 post "Foo/Bar/Baz" 代码而不是实际代码,但在这种情况下它有点困难并且 classes 会自己提出(不相关的)问题,我不想讨论:P
我已将所有答案投票为 "thank you";然而,由于其中 none 是实际的解决方案,再次因为我是个笨蛋并且 post 不正确 code/information,我已经 post 编辑了我自己的答案。
我有这两个 classes:
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 现在希望我在 Foo
上创建 属性 BarId
和 Bar
,但我不希望那样。我希望将 属性 命名为 PrimaryBar。我在 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
class 上。参见
要事第一。
如果你的 FK 属性 是一个可以为 null 的整数,就像我在你的代码中看到的那样,你的关系将是 0..1-N 而不是 1-N,因为它是一个可以为 null 的外键。
其次,我对属性语法不是很熟悉,因为它不适合描述您的模型,并且它会使您的对象与 EF 相关数据混淆。首选方法是在继承 EntityTypeConfiguration<T>
的单独 class 中声明 EF 映射,其中 T
是您的 class.
现在给定您的 classes,首先您必须在 Bar
上添加一个 属性 来映射 N 引用,如下所示:
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")]
根据 the documentation,提供给 ForeignKeyAttribute
的 Name
应该是 属性 名称,而不是类型或 table 名称。因此,将您的代码更改为:
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; }
非常抱歉,但 none 的答案是正确的。也就是说:他们 是 正确的(可能),但我 post 编辑了我的示例代码以解决问题。首先我忘记重命名一些 types/properties,然后我在 post 编辑的错误消息中发现了一个错误。最后我发现我忘了 post 我在 Bar
class:
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
class 上包含 1:0..N 和 Bar
:
class Foo {
public virtual ICollection<Bar> Bars { get; set; }
}
我添加了这个合集等等;现在一切正常。
哦,我 确实 必须将 ForeignKey 更改为 PrimaryBar
而不是 Bar
确实如大多数答案所建议的那样。
我非常抱歉和我的过失:所有他妈的都是我的,而且只是我自己的。我通常不喜欢 post "Foo/Bar/Baz" 代码而不是实际代码,但在这种情况下它有点困难并且 classes 会自己提出(不相关的)问题,我不想讨论:P
我已将所有答案投票为 "thank you";然而,由于其中 none 是实际的解决方案,再次因为我是个笨蛋并且 post 不正确 code/information,我已经 post 编辑了我自己的答案。