【问题标题】:Why does Entity Framework not respect my Foreign Key?为什么实体框架不尊重我的外键?
【发布时间】:2016-04-28 06:52:23
【问题描述】:

我正在编写没有现有数据库的实体框架模型Code-First。在我的对象上,我已经明确声明了我的一对多外部关系,并且声明为延迟加载导航属性,如下所示:

用户记录类

[Key]
public long ID { get; set; }

public virtual List<WorkItemRecord> WorkItemsAuthored { get; set; } // authored work items

WorkItemRecord 类:

[Key]
public long ID { get; set; }

public long AuthorID { get; set; } // user ID of the author
public virtual UserRecord Author { get; set; } // navigation lazy-loaded property

在 WorkItemRecord 类中维护外键作为 ID 和导航属性的想法是,如果我只需要实际底层作者的用户 ID,我可以直接引用它而无需调用属性并引发另一个数据库查找。

问题是,当 EF 创建数据库架构时,它并没有将它们绑定在一起。它创建单独的列:AuthorIDUserRecord_ID

起初我想这可能是因为我的财产是Author 而不是User。但是,即使我使用 property 属性明确指定它...

[ForeignKey("Author")]
public long AuthorID { get; set; }
public virtual UserRecord Author { get; set; }

...我仍然在生成的架构中得到相同的两列。

还尝试将装饰器放在其他属性上...

public long AuthorID { get; set; }
[ForeignKey("AuthorID")]
public virtual UserRecord Author { get; set; }

...仍然得到相同的结果。

如果可能,我想避免使用 Fluent API,但如果我无法获得任何其他解决方案,我愿意接受。

有什么想法吗?

谢谢!

更新

感谢大家的帮助! Fluent API 运行良好,但使用反向属性装饰器修复数据注释被证明要容易得多。最终解决方案:

UserRecord 类:

public long ID { get; set; }
public virtual List<WorkItemRecord> WorkItemsAuthored { get; set; }

WorkItemRecord 类:

public long ID { get; set; }

[ForeignKey("Author")]
public long AuthorUserID { get; set; }

[InverseProperty("WorkItemsAuthored")]
public virtual UserRecord Author { get; set; }

微软也有一篇文章讨论这个特定问题:

https://msdn.microsoft.com/en-us/data/jj591583.aspx#Relationships

【问题讨论】:

  • 给我们看看 UserRecord 的代码?
  • 听起来可能有点傻,但UserRecord.ID 属性的类型是否与AuthorID 属性的类型匹配?他们都是long吗?
  • 是的。更新了代码以包含它。

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


【解决方案1】:

在你的DbContext 类中添加这个到你的OnModelCreating 方法中。

modelBuilder.Entity<Book>() //Guessing at your class name
    .HasRequired(e => e.Author)
    .WithMany(e => e.Books)
    .HasForeignKey(e => e.AuthorID);

这将强制执行约束。

【讨论】:

  • 这行得通,谢谢!但是,我仍然希望找到一种方法来使用装饰器属性而不是流畅的 API,因为这样将来另一个开发人员会更容易接受
【解决方案2】:

引用属性应该足以让 EF 识别一对多关系,但您是否在 UserRecord 类中也有导航属性?

public class UserRecord
{
    /* other properties */
    public virtual List<WorkItemRecord> WorkItemsAuthored { get; set; }
}

也许有一个小细节导致 EF 无法识别外键。

更新:UserRecord 类中尝试InverseProperty,如下所示:

[InverseProperty("WorkItemsAuthored")]
public virtual UserRecord Author { get; set; } // navigation lazy-loaded property

来自 Julia Lerman 和 Rowan Miller 编写的“编程实体框架:代码优先”:

...您可能会遇到实体之间存在多种关系的情况。在这些情况下,Code First 将无法确定哪些导航属性匹配。

我假设UserRecord 类有不止一个List&lt;WorkItemRecord&gt;

【讨论】:

  • 是的。更新了相关代码以包含更多上下文。
  • 更新了我的答案,以便您可以使用数据注释。这可能会解决您的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-04-02
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多