我使用EF 4.3代码优先,并有这个通用的Category实体来组织各种类型的内容:
public enum ContentType { Articles,Videos }; public class Category { public long ID { get; set; } public long? ParentCategoryID { get; set; } internal int ContentTypeValue { get; set; } public string Title { get; set; } public virtual Category ParentCategory { get; set; } public virtual ICollection<Category> ChildCategories { get; set; } public ContentType ContentType { get { return (ContentType) ContentTypeValue; } set { ContentTypeValue = (int) value; } } }
这使用以下定义映射到数据库(我使用的是辅助类,但Map只是指实体的具体模型构建器):
Map.Property( e => e.ContentTypeValue ).Isrequired().HasColumnName( "ContentType" ); Map.Property( e => e.Title ).Isrequired().HasMaxLength( 200 ); Map.HasOptional( e => e.ParentCategory ).WithMany( r => r.ChildCategories ).HasForeignKey( e => e.ParentCategoryID ).WillCascadeOnDelete( false );
请注意,Category不提供对其他实体类型的引用(自身除外).
public class Article { public long ID { get; set; } public long CategoryID { get; set; } public string Title { get; set; } public string Body { get; set; } public virtual Category Category { get; set; } } Map.Property( e => e.Title ).Isrequired().HasMaxLength( 50 ); Map.Property( e => e.Body ).Isrequired().HasMaxLength( 4000 ); Map.Hasrequired( e => e.Category ).WithMany().HasForeignKey( e => e.CategoryID ).WillCascadeOnDelete( false );
这很好,并创建一个带有PK(ID)和FK(CategoryID)的Article表到Category表.
下一步是为Video添加一个类似的实体和映射定义,它也按预期工作.
public class Video { public long ID { get; set; } public long CategoryID { get; set; } public string Title { get; set; } public string FileName { get; set; } public virtual Category Category { get; set; } } Map.Property( e => e.Title ).Isrequired().HasMaxLength( 50 ); Map.Property( e => e.FileName ).Isrequired().HasMaxLength( 200 ); Map.Hasrequired( e => e.Category ).WithMany().HasForeignKey( e => e.CategoryID ).WillCascadeOnDelete( false );
但是,现在我希望Article能够直接引用特定的视频(无论它们属于哪个类别),因此本质上是两者之间的1:1(必需:可选)引用.
public class Article // broken { public long ID { get; set; } public long CategoryID { get; set; } public long? VideoID { get; set; } public string Title { get; set; } public string Body { get; set; } public virtual Category Category { get; set; } public virtual Video Video { get; set; } }
为了映射该类,我将使用以下内容:
Map.Property( e => e.Title ).Isrequired().HasMaxLength( 50 ); Map.Property( e => e.Body ).Isrequired().HasMaxLength( 4000 ); Map.Hasrequired( e => e.Category ).WithMany().HasForeignKey( e => e.CategoryID ).WillCascadeOnDelete( false ); Map.HasOptional( e => e.Video ).WithMany().HasForeignKey( e => e.VideoID ).WillCascadeOnDelete( false );
一旦我添加了这样的引用,EF就无法使用dbupdateException创建数据库模式,其错误消息是“无法确定(约束名称)的主要结束”.多个添加的实体可能具有相同的主键. “
我可以通过没有视频参考类别(或没有文章参考视频,如在所示的第一个代码中)来解决问题,但这将破坏类类的通用目的并迫使我维护ArticleCategories,VideoCategories等.
为了完全清楚我需要什么,这里是我想要最终的模式(注意:视频中的CategoryID不应该是可空的,与图像相反):
如何使用代码优先的流利表示法定义这种关系?
解决方法
无论如何,这是我的确切代码:https://gist.github.com/1961958
这就是Update-Database:https://gist.github.com/1961961生成的sql
编辑:操作,我没有看到@BalazsTihanyi完全相同的答案,对不起.
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 [email protected] 举报,一经查实,本站将立刻删除。