2011-09-08 27 views
10

he muchos-a-muchos relación definida de esta manera:Entity Framework - consultar una relación muchos-a-muchos tabla de relación

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

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

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

Estoy tratando de obtener una lista de los empleados, dada una lista o RoleIDs:

private MyDBEntities _entities; 

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

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

Pero si yo trato de hacer _entities.EmployeeRoles, no hay ningún objeto EmployeeRoles. Mi edmx se ve así:

enter image description here

por lo que es el reconocimiento de la relación entre las dos tablas, pero no es la creación de un objeto de entidad para EmployeeRoles.

¿Cómo puedo obtener una lista distinta de empleados con una lista de ID de función?

Respuesta

28

La relación entre las tablas Rol y Empleado se representa como una propiedad de navegación: cada propiedad Employees en la entidad Role solo incluirá a los Empleados que tengan esta función en particular.

Poniéndolo al revés: la propiedad de cada empleado Roles solo contiene las funciones que tiene un empleado en particular.

dado un conjunto de roles roleIds a buscar se puede usar esto para obtener la lista de los empleados que tienen un papel dentro de ese conjunto:

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

Editar:

La otra forma de obtener los empleados es atacar el problema desde el otro lado de la relación (comenzando con el rol, no el empleado). Esto es más probable no es tan eficiente como el primer enfoque, ya que tenemos empleados de de-duplicación (de lo contrario es decir los empleados con dos papeles aparecerían dos veces):

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

Lol, solo iba a publicar esto como una alternativa a su primera solución (con 'Distinct', etc.), pero ahora ya no es una alternativa. ¿Puedes dejar tu primera solución como otra opción en tu respuesta? Era una forma interesante, o era algo malo con eso? – Slauma

+0

@Slauma: Sí, es una alternativa, pero parecía más directo después de ver el problema, así que me puse a rayar el primer enfoque, déjame desenterrarlo de nuevo ;-) – BrokenGlass

3

Tal vez?

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