2011-12-09 76 views
17

我有以下查詢:如何訂購EF實體的子集

public IEnumerable<Team> GetAllTeamsWithMembers(int ownerUserId) 
     { 
      return _ctx.Teams 
       .Include(x => x.TeamMembers) 
       .Where(x => x.UserId == ownerUserId) 
       .OrderBy(x => x.Name).ToList(); 

     } 

如何去他們的名字訂購的球隊,然後讓各隊排序的所有子成員的名稱?

看來,我需要創建一個新的DTO類並使用select。我想使用已經創建的EF實體,在這種情況下,Team具有成員的導航屬性。我從我的存儲庫層返回IEnumerable<Team>

在EF中似乎沒有排序子集合的整潔方式。誰能幫忙?

+1

以下是各種示例:http://stackoverflow.com/a/7181574/270591,http://stackoverflow.com/a/7528266/270591,http://stackoverflow.com/a/7395406/270591 – Slauma

+0

可能的重複[EF 4.1 code-first:如何使用Include和/或Select方法命令導航屬性?](http://stackoverflow.com/questions/7522784/ef-4-1-code-first-how-當使用包括和 - 或) –

回答

16

加載後您可以加載數據並在內存中排序。

IEnumerable<Team> teams = _ctx.Teams 
      .Include(x => x.TeamMembers) 
      .Include(x => x.TeamMembers.Select(u => u.User)) 
      .Where(x => x.UserId == ownerUserId) 
      .OrderBy(x => x.Name).ToList(); 

foreach (var team in teams) 
{ 
    team.TeamMembers = team.TeamMembers.OrderBy(m => m.Name); 
    foreach (var teamMember in team.TeamMembers) 
    { 
     teamMember.Users = teamMember.Users.OrderBy(u => u.Name); 
    } 
} 

或者您可以使用Projections並使用EF的更改跟蹤對您的集合進行排序。 Here is an example過濾一個包含,但同樣適用於Ordering。

+2

感謝你,簡單而有效。我認爲可能會有更多LINQish,不喜歡循環,但它可以完成這項工作! – jaffa

2

,你可以放棄自己的球隊,他們的團隊成員到一個匿名類型(很可能不是你想要的),像這樣:

public IEnumerable<Team> GetAllTeamsWithMembers(int ownerUserId) 
{ 
    return (from t in _ctx.Teams 
     where t.UserId == ownerUserId 
     select new { 
      Team = t, 
      TeamMembers = t.TeamMembers.OrderBy(m => m.Name) 
     }).ToList() 
} 

然後,您可以通過他們的循環:

foreach(Team team in GetAllTeamsWithMembers(1234)) 
{ 
    string teamName = team.Team.Name; 
    string firstTeamMemberName = team.TeamMembers.First().Name; 
} 

更新:爲了記錄,我的意見是不使用此解決方案,而是在循環中或在渲染/綁定期間對每個集合進行排序。

我刪除了第二個解決方案,因爲有人指出EF無法選擇實體。

+0

第二個選項不能工作,因爲LINQ to Entities不允許投影到實體中。 – Slauma

+0

如果在ToList()後面添加一個.Select(a => a.Team),則第一個選項可以正常工作。 –

+0

@Slauma我不知道。 –