2011-09-08 12 views
10

Mam wiele do wielu relacji zdefiniowane tak:Entity Framework - odpytywanie wiele-do-wielu tabeli relacji

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

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

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

Próbuję uzyskać listę pracowników, biorąc pod uwagę listę lub RoleIDs:

private MyDBEntities _entities; 

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

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

Ale jeśli spróbować i zrobić _entities.EmployeeRoles, nie ma EmployeeRoles obiektu. Moja edmx wygląda następująco:

enter image description here

Więc to rozpoznawanie relacji między dwiema tabelami, ale to nie jest stworzenie obiektu jednostki za EmployeeRoles.

Jak uzyskać oddzielną listę pracowników z listą identyfikatorów ról?

Odpowiedz

28

Relacja między tabelami Rola i pracownik jest reprezentowana jako właściwość nawigacji - każda właściwość Employees w jednostce Role będzie zawierała tylko pracowników, którzy pełnią tę szczególną rolę.

Odwrotnie - każda własność pracownika Roles zawiera tylko role poszczególnych pracowników.

Biorąc pod uwagę zestaw ról roleIds szukać można to wykorzystać, aby uzyskać listę pracowników, które mają pewną rolę w tym zestawie:

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

Edit:

Innym sposobem poproś pracowników, aby zaatakowali problem z drugiej strony relacji (zaczynając od roli, a nie od pracownika). Jest to najprawdopodobniej nie tak skuteczny jak w pierwszym podejściu, ponieważ mamy do de-duplikatów pracowników (w przeciwnym razie pracownikom tj dwie role byłyby pojawiają się dwa razy):

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, chciałem to opublikować jako alternatywę dla twojego pierwszego rozwiązania (z 'Distinct' itp.), Ale teraz nie ma już żadnej alternatywy. Czy możesz zostawić swoje pierwsze rozwiązanie jako kolejną opcję w swojej odpowiedzi. To był interesujący sposób, czy coś było z nim nie tak? – Slauma

+0

@Slauma: Tak, to jest alternatywa - ale wydawało mi się to bardziej oczywiste po przyjrzeniu się problemowi, więc podrapałem pierwsze podejście - pozwól, że znów je wykopię ;-) – BrokenGlass

3

Może?

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