EF Core Code First模式下组织、分支机构、建筑所属关系实体设计问题
关系类型判定
- 组织归属于其他组织:属于自引用一对多关系,1个父组织可对应多个子组织,单个子组织仅能归属1个父组织。
- 分支机构归属于组织/其他分支机构:属于「多态一对多 + 自引用一对多」组合关系,1个组织/父分支机构可对应多个子分支机构,单个子分支机构仅能归属1个上级(组织或其他分支机构)。
- 建筑归属于分支机构:属于标准一对多关系,1个分支机构可对应多个建筑,单个建筑仅能归属1个分支机构。
现有设计合理性评估
你目前的设计存在明显缺陷,不合理:
- 未覆盖组织自关联需求:缺少「组织归属于其他组织」的自引用关系定义。
- 未覆盖分支机构多上级需求:仅定义了分支机构归属组织的关系,缺少分支机构归属其他分支机构的自引用关系。
- 实体关联偏差:需求明确要求建筑归属分支机构,你写的
Branch 1-n Vehicle完全偏离需求,推测是笔误,应该替换为Branch 1-n Building。
推荐EF Core Code First实现示例
// 组织实体 public class Organization { public int Id { get; set; } public string Name { get; set; } // 自关联外键,顶级组织该字段为null public int? ParentOrganizationId { get; set; } // 导航属性:父组织 public Organization ParentOrganization { get; set; } // 导航属性:子组织集合 public ICollection<Organization> ChildOrganizations { get; set; } // 导航属性:下属分支机构集合 public ICollection<Branch> Branches { get; set; } } // 分支机构实体 public class Branch { public int Id { get; set; } public string Name { get; set; } // 归属组织的外键,归属分支时该字段为null public int? OrganizationId { get; set; } // 归属父分支的外键,归属组织时该字段为null public int? ParentBranchId { get; set; } // 导航属性:归属的组织 public Organization Organization { get; set; } // 导航属性:父分支 public Branch ParentBranch { get; set; } // 导航属性:子分支集合 public ICollection<Branch> ChildBranches { get; set; } // 导航属性:下属建筑集合 public ICollection<Building> Buildings { get; set; } } // 建筑实体 public class Building { public int Id { get; set; } public string Name { get; set; } // 非空外键,必须归属分支 public int BranchId { get; set; } // 导航属性:归属的分支 public Branch Branch { get; set; } }
如果需要避免两个上级外键同时有值,可以在DbContext的OnModelCreating方法中添加校验约束:
protected override void OnModelCreating(ModelBuilder modelBuilder) { modelBuilder.Entity<Branch>() .HasCheckConstraint("CK_Branch_Parent", "OrganizationId IS NOT NULL OR ParentBranchId IS NOT NULL") .HasCheckConstraint("CK_Branch_SingleParent", "NOT (OrganizationId IS NOT NULL AND ParentBranchId IS NOT NULL)"); }
内容的提问来源于stack exchange,提问作者User456
相关产品推荐
相关产品推荐

