[EF5.0CODE 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);   // 映射列
        }
原文地址:https://www.cnblogs.com/tukzer/p/3088338.html