[EF5.0-CODE FIRST]多对一及自关联映射的处理
在CODE FIRST实践中发现多对多映射有较多的资料,处理起来反而不怎么麻烦,而一对多和自关联(Self-reference)则往往处理比较复杂。典型的配置如下:
/// <summary> /// 系统菜单项目配置 /// </summary> public class Menu : BaseEntity { public int MenuId{get;set;} /// <summary> /// 父菜单 /// </summary> public virtual Menu ParentMenu { get; set; } public int? ParentId { get; set; } /// <summary> /// 菜单名称 /// </summary> [Required] public string MenuName { get; set; } /// <summary> /// 菜单描述信息 /// </summary> public string MenuDesc { get; set; } /// <summary> /// 排序 /// </summary> public int MenuIndex { get; set; } /// <summary> /// 包含的子菜单 /// </summary> public virtual IList<Menu> ChildMenus { get; set; } }
代码中定义了一个树状的一对多自关联实体。注意其中的一部分配置。
-
ParentId 被配置为可控的INT类型,否则在Migration时会保存;
- 如果在同一个Context中一次插入多条数据,则需要考虑其MenuId重复(都是初始值)的问题。
根据上面的导航属性的配置,需要在OnModelCreating中增加配置说明,以便将映射关系绑定到属性上。如果此处有问题,会在后续数据保存时报字段不存在的错误。
protected override void OnModelCreating(DbModelBuilder builder) { // 菜单的自身多对一映射 builder.Entity<EPMenu>() .HasOptional(p => p.ParentMenu) // 存在0或者1个父节点 .WithMany(p => p.ChildMenus) // 包括n个子节点 .HasForeignKey(m => m.ParentId); // 映射列 }