实体框架 - 查询多对多关系表

时间:2011-09-08 19:28:58

标签: c# asp.net linq entity-framework

我有如此定义的多对多关系:

Employees
--------------
EmployeeID (PK)

Roles
--------------
RoleID (PK)

EmployeeRoles
--------------
EmployeeID (PK, FK)
RoleID (PK, FK)

我正在尝试获取一个Employees列表,给出一个列表或RoleIDs:

private MyDBEntities _entities;

public SqlEmployeesRepository(MyDBEntities entities)
{            
    _entities = entities;
}

public IQueryable<Employee> GetEmployeesForRoles(int[] roleIds)
{
    // get employees
}

但是如果我尝试做_entities.EmployeeRoles,就没有EmployeeRoles对象。我的edmx看起来像这样:

enter image description here

所以它识别了两个表之间的关系,但它没有为EmployeeRoles创建一个实体对象。

如何在给定角色ID列表的情况下获得一份明确的员工列表?

2 个答案:

答案 0 :(得分:31)

表Role和Employee之间的关系表示为导航属性 - Employees实体中的每个Role属性只包含具有此特定角色的Employees。

反过来说 - 每个Employee的Roles属性只包含特定员工的角色。

给定一组要查找的角色roleIds,您可以使用此角色获取在该集合中具有角色的员工列表:

public IQueryable<Employee> GetEmployeesForRoles(int[] roleIds)
{
    var employees = _entities.Employees
                             .Where( x=> x.Roles.Any(r => roleIds.Contains(r.RoleID)))
   return employees;
}

修改

获得员工的另一种方法是从关系的另一方面解决问题(从角色开始,而不是从员工开始)。这很可能不如第一种方法那么有效,因为我们必须对员工进行重复删除(否则,即两个角色的员工会出现两次):

public IQueryable<Employee> GetEmployeesForRoles(int[] roleIds)
{
    var employees = _entities.Roles
                             .Where( r => roleIds.Contains(r.RoleID))
                             .SelectMany( x=> x.Employees)
                             .Distinct()
   return employees;
}

答案 1 :(得分:3)

也许?

var results = from r in db.Roles
              where roleIds.Contains(r.Id)
              select r.Employees;