2012-05-02 152 views
0

我需要從兩個查詢中創建一個新模型。我有一個成員實體和一個成員團隊實體,它們都具有彼此的引用。我需要的是所有成員名單,並知道該成員是否分配給給定的團隊。將兩個Linq查詢合併爲一個無foreach循環的單個查詢

我目前有以下代碼可以工作,但對我來說似乎笨重,我希望有人有更好的方法來創建這個組合列表只使用Linq語句(沒有foreach)。基本上,代碼獲取所有成員的列表,獲取分配給團隊的成員的另一個列表,然後使用foreach循環查看該成員是否分配給團隊。

int teamId = 1; 
    var model = new SelectedMemberListModel(); 
    List<Member> allMembers = _unitOfWork.RepositoryFor<Member>().All().ToList(); 
    List<Member> teamMembers = _unitOfWork.RepositoryFor<MemberTeam>().AllIncluding(x => x.Members).Single(x => x.Id == teamId).Members.ToList(); 
    List<SelectedMemberModel> membersWithTeamSelected = new List<SelectedMemberModel>(); 
    foreach (var member in allMembers) 
    { 
    SelectedMemberModel selectedMemberModel = new SelectedMemberModel(); 
    selectedMemberModel.FirstName = member.FirstName; 
    selectedMemberModel.LastName = member.LastName; 
    if(teamMembers.Contains(member)) 
    { 
     selectedMemberModel.Selected = true; 
    } 
    membersWithTeamSelected.Add(selectedMemberModel); 
    } 

如果需要了解我的模型更好,這裏有我的實​​體:

public class Member 
{ 
    public int Id { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public int TeamId { get; set; } 
    public virtual MemberTeam Team { get; set; } 
    //... Other properties here... 
} 

public class MemberTeam 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public ICollection<Member> Members { get; set; } 
} 

public class SelectedMemberModel 
{ 
    public int MemberId { get; set; } 
    public string FirstName { get; set; } 
    public string LastName { get; set; } 
    public bool Selected { get; set; } 
} 

回答

1

我不能完全肯定,如果我理解正確的你 - 但我認爲這可能是你所需要的查詢?

這一次將返回...模型對象列表只針對選定的成員(那些在teamMembers列表):

var assignedOnly = allMembers 
        .Where(m => teamMembers.Contains(m)) 
        .Select(m => new SelectedMemberModel() { 
         FirstName = m.FirstName, LastName = m.LastName, 
         Selected = true, MemberId = m.Id}); 

而這個查詢應該返回所有的成員...模型對象,其中所選擇的屬性基於與上述相同的條件來設定:

var allToModel = from m in allMembers 
        let selected = teamMembers.Contains(m) 
        select new SelectedMemberModel() { 
         FirstName = m.FirstName, LastName = m.LastName, 
         Selected = selected, MemberId = m.Id }; 

無論如何,我不希望這是比foreach循環更有效。

UPDATE:

好吧,我誤解了意圖 - 我想你想擺脫的foreach所以我忽略任何東西拆開循環,但是它非常有意義,使只有一個DB調用。
我對實體框架不太熟悉,但我認爲下面的linq語句就足夠了 - 它僅使用teamId值在allMembers列表上運行,以評估成員是否在選定的團隊中。
讓我知道這是否能解決您的問題。

var selectedMemberModelList = allMembers 
           .Select(m => new SelectedMemberModel() { 
            FirstName = m.FirstName, LastName = m.LastName, 
            MemberId = m.Id, Selected = m.Id == teamId}) 
           .ToList(); 
+0

喬安娜,感謝您的反饋意見。你的第二種方法就是我所期待的。不過,我看到你對效率的觀點。它看起來更乾淨,但它仍然需要對數據庫進行兩次查詢(針對allMembers和teamMembers)。我希望得到一個單一的選擇聲明,但你的建議仍然更清晰。感謝您的意見。 – bigmac

+0

@bmccleary - 我已經改變了查詢,現在看來似乎更簡單了。它似乎也在做你想做的事 - 參見更新2。 –