首先,如果您发现此设计存在任何问题,请随时告诉我。
目标是拥有公司,每个公司都有一些部门。
部门可以在公司之间共享。
如:
Company 1
可以Department 1, 2 and 3.
Company 2
可以Department 1, 5, 8 and 9.
BusinessUnits
可以访问departments
。
但这取决于与department
相关联的公司。
BusinessUnit 1
可能有权访问Department 1
Company 1
,但无法访问Department 1
Company 2
。
CompanyDepartment
配置表非常明显。
它将公司与(可能)多个部门联系起来。
CompanyDepartmentBusinessUnit
配置表用于将BusinessUnits
与Departments
的{{1}}相关联。
在此表格中,Company
和CompanyId
形成了DepartmentId
主键的复合外键(即:CompanyDepartment
和CompanyId
)。
我在Entity Framework中使用了Database-First方法。
对于简单的联结表,我已覆盖DepartmentId
中的OnModelCreating
方法。
我是如何做到这一点的一个例子:
我现在的问题是:我如何为DbContext
关系执行此操作?
假设我的用户选择查看CompanyDepartmentBusinessUnit
的部门。
我想过滤链接到Company 1
的所有Departments
,但对用户所在的Company 1
也是可见的(例如BusinessUnit
)。
提前感谢您,享受您的假期!
答案 0 :(得分:2)
EF仅允许您使用隐式联结表(1)它没有其他列;(2)如果它不被多对多关系的两端不同的其他实体引用。
CompanyDepartment
满足条件(1),但不满足(2),因为它是从CompanyDepartmentBusinessUnit
引用的,因此您需要使用具有两个一对多关系的explcit实体。
一旦你这样做,可以看出现在CompanyDepartmentBusinessUnit
满足两个条件,因此可以使用BusinessUnit
和CompanyDepartment
的隐式联结表进行建模。
话虽如此,最终模型将是这样的:
public class Company
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<CompanyDepartment> DepartmentLinks { get; set; }
}
public class Department
{
public int Id { get; set; }
public string Name { get; set; }
public ICollection<CompanyDepartment> CompanyLinks { get; set; }
}
public class BusinessUnit
{
public int Id { get; set; }
public string Name { get; set; }
public bool IsPersonal { get; set; }
public ICollection<CompanyDepartment> CompanyDepartments { get; set; }
}
public class CompanyDepartment
{
public int CompanyId { get; set; }
public int DepartmentId { get; set; }
public Company Company { get; set; }
public Department Department { get; set; }
public ICollection<BusinessUnit> BusinessUnits { get; set; }
}
并考虑默认的EF约定,使用以下最小流畅配置:
modelBuilder.Entity<Company>().ToTable("Company");
modelBuilder.Entity<Department>().ToTable("Department");
modelBuilder.Entity<BusinessUnit>().ToTable("BusinessUnit");
modelBuilder.Entity<CompanyDepartment>().ToTable("CompanyDepartment");
modelBuilder.Entity<CompanyDepartment>()
.HasKey(e => new { e.CompanyId, e.DepartmentId });
modelBuilder.Entity<CompanyDepartment>()
.HasMany(e => e.BusinessUnits)
.WithMany(e => e.CompanyDepartments)
.Map(m => m
.MapLeftKey("CompanyId", "DepartmentId")
.MapRightKey("BusinessUnitId")
.ToTable("CompanyDepartmentBusinessUnit")
);