2011-09-08 174 views
10

我已經一個多到許多定義,像這樣的關係:實體框架 - 查詢許多一對多關係表

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

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

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

我試圖讓員工的名單,給定一個列表或者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列表?

回答

28

表Role和Employee之間的關係表示爲導航屬性 - Role實體中的每個Employees屬性將只包含具有此特定角色的僱員。

換個角度來看 - 每個員工的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; 
} 
+0

大聲笑,我只是想發佈這個作爲替代你的第一個解決方案(與'獨特'等),但現在它不再是替代品。你能否將你的第一個解決方案作爲你答案的另一種選擇?這是一種有趣的方式,或者是有什麼問題? – Slauma

+0

@Slauma:是的,它是一種替代方案 - 但在看到問題後,這看起來更加直截了當,所以我抓住了第一種方法 - 讓我再次挖掘它;-) – BrokenGlass

3

也許?

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