[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);   // 映射列

        }

 

你可能感兴趣的:(first)