实体框架6导航属性别名?

时间:2015-01-14 08:29:41

标签: c# entity-framework entity-framework-6

我有这两个类:

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上创建一个属性BarFoo,但我不希望这样。我希望将该属性命名为主要栏。我在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)属性(最好使用属性,尽管使用DbModelBuilder覆盖中的OnModelCreating是一个选项太?

修改

想出来。我错过了一个:

public virtual ICollection<Bar> Bar { get; set; }

在我的Foo课程上。有关说明,请参阅here

4 个答案:

答案 0 :(得分:4)

根据the documentation,提供给Name的{​​{1}}应该是属性名称,而不是类型或表名称。所以将代码更改为:

ForeignKeyAttribute

或者:

public int? PrimaryBarId { get; set; }
[ForeignKey("PrimaryBarId")]
public virtual Bar PrimaryBar { get; set; }

答案 1 :(得分:2)

首先要做的事情。

如果您的FK属性是我在代码中看到的可以为空的int,那么您的关系将是0..1-N而不是1-N,因为它是可以为空的外键。

其次,我对属性语法不是很熟悉,因为描述你的模型并不理想,它会使你的对象与EF相关的数据混乱。首选方法是在单独的类中声明EF映射,该类继承EntityTypeConfiguration<T>,其中T是您的类。

现在给出你的课程,首先你必须在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

答案 2 :(得分:2)

根据MSDN名称参数不是实体名称,而是导航属性名称(在您的情况下,因为它比这更复杂)。

您应该更改以下代码:

[ForeignKey("Bar")]

为:

[ForeignKey("PrimaryBar")]

答案 3 :(得分:-2)

我非常抱歉,但没有一个答案是正确的。那就是:他们 正确(可能)但我发布了我的示例代码错误的问题。首先我忘了重命名一些类型/属性,然后我在发布的错误消息中发现了一个错误。最后我发现我忘记在我的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课程中的以下内容,其中包含Bar的1:0..N:

class Foo {
    public virtual ICollection<Bar> Bars { get; set; }
}

我添加了这个集合et voila;现在一切正常。

哦,我确实必须将ForeignKey更改为PrimaryBar,而不是Bar,而大多数答案都是如此。

我非常抱歉和mea culpa:所有f * ckups都是我的和我自己的。我通常不喜欢发布&#34; Foo / Bar / Baz&#34;代码而不是实际的代码,但在这种情况下,它有点困难,类会自己提出(无关)问题,我不想讨论:P

我赞成所有答案为&#34;谢谢你&#34 ;;但是因为它们都不是真正的解决方案,再次因为我是一个笨蛋而且发布错误的代码/信息,我已经发布了自己的答案。