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 1
的 Department 1
,但不应该能够访问 Company 2
的 Department 1
。
CompanyDepartment
配置 table 非常明显。
它 link 是一家(可能)多个部门的公司。
CompanyDepartmentBusinessUnit
配置 table 用于 link BusinessUnits
到 Departments
的 Company
。
在这个table中,CompanyId
和DepartmentId
形成了CompanyDepartment
主键的复合外键(即:CompanyId
和DepartmentId
以及)。
我在 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 为 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")
);
我设计了一个数据库,非常注意规范化。
这是它的一部分:
首先,如果您发现此设计有任何问题,请随时告诉我。
目标是有公司,每个公司都有一些部门。
公司之间可以共享部门。
如:
Company 1
可以有 Department 1, 2 and 3.
Company 2
可以有 Department 1, 5, 8 and 9.
BusinessUnits
将可以访问 departments
。
但这取决于 department
被 link 编辑的公司。
BusinessUnit 1
可能有权访问 Company 1
的 Department 1
,但不应该能够访问 Company 2
的 Department 1
。
CompanyDepartment
配置 table 非常明显。
它 link 是一家(可能)多个部门的公司。
CompanyDepartmentBusinessUnit
配置 table 用于 link BusinessUnits
到 Departments
的 Company
。
在这个table中,CompanyId
和DepartmentId
形成了CompanyDepartment
主键的复合外键(即:CompanyId
和DepartmentId
以及)。
我在 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 为 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")
);