为什么实体框架不尊重我的外键?

时间:2016-04-26 20:16:20

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

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

UserRecord类

[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。但是,即使我使用属性属性明确指定它...

[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

2 个答案:

答案 0 :(得分:2)

在您的DbContext课程中,将其添加到您的OnModelCreating方法。

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

这将强制执行约束。

答案 1 :(得分:1)

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

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

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

<强>更新InverseProperty课程中尝试UserRecord,如下所示:

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

来自&#34;编程实体框架:代码优先&#34;由Julia Lerman和Rowan Miller撰写:

  

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

我认为UserRecord类有多个List<WorkItemRecord>