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 上创建 属性 BarIdBar,但我不希望那样。我希望将 属性 命名为 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,提供给 ForeignKeyAttributeName 应该是 属性 名称,而不是类型或 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 编辑了我自己的答案。