我正在编写没有现有数据库的实体框架模型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创建数据库模式时,它不会将它们绑定在一起。它会创建单独的列:AuthorID
和UserRecord_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
答案 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>
。