Entity Framework:使用多个联结表

Entity Framework: Using Multiple Junction Tables

我设计了一个数据库,非常注意规范化。 这是它的一部分:

首先,如果您发现此设计有任何问题,请随时告诉我。

目标是有公司,每个公司都有一些部门。 公司之间可以共享部门。 如: Company 1 可以有 Department 1, 2 and 3. Company 2 可以有 Department 1, 5, 8 and 9.

BusinessUnits 将可以访问 departments。 但这取决于 department 被 link 编辑的公司。

BusinessUnit 1 可能有权访问 Company 1Department 1,但不应该能够访问 Company 2Department 1

CompanyDepartment 配置 table 非常明显。 它 link 是一家(可能)多个部门的公司。

CompanyDepartmentBusinessUnit 配置 table 用于 link BusinessUnitsDepartmentsCompany。 在这个table中,CompanyIdDepartmentId形成了CompanyDepartment主键的复合外键(即:CompanyIdDepartmentId以及)。

我在 Entity Framework 中使用数据库优先的方法。 对于简单的联结 tables,我在 DbContext.

中覆盖了 OnModelCreating 方法

我如何做到这一点的一个例子:

我现在的问题是:如何为 CompanyDepartmentBusinessUnit 关系执行此操作?

假设我的用户选择查看 Company 1 的部门。 我想过滤所有 linked 到 Company 1 但对用户所在的 BusinessUnit 可见的所有 Departments(例如 Business Unit 2) .

提前致谢,祝您假期愉快!

EF 允许您使用隐式连接 table 仅当 (1) 它没有额外的列并且 (2) 如果它没有被不同于多对多两端的其他实体引用关系。

CompanyDepartment 满足条件 (1),但不满足条件 (2),因为它是从 CompanyDepartmentBusinessUnit 引用的,因此您需要使用具有两个一对多关系的显式实体。

一旦你这样做,可以看出现在 CompanyDepartmentBusinessUnit 满足两个条件,因此可以用隐式连接 table 为 BusinessUnitCompanyDepartment 建模。

话虽如此,最终的模型应该是这样的:

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")
    );