实体框架 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并在FooBar,但我不希望这样。我希望将该属性命名为主栏。我对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课上。有关说明,请参阅此处。

实体框架 6 导航属性别名

根据文档,提供给ForeignKeyAttributeName应该是属性名称,而不是类型或表名称。因此,请将您的代码更改为:

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

我对所有答案都

投了赞成票作为"谢谢";但是,由于它们都不是实际的解决方案,再次因为我是一个笨蛋并且发布了不正确的代码/信息,我发布了自己的答案。