2010-05-19 142 views
0

所以我剛剛開始使用linq以及使用lambda表達式。我試圖獲得一些我想要的數據時遇到了一個小小的呃逆。這個方法應該返回打開的或從吉拉使用lambda表達式和linq

這裏所有正在進行的項目清單是代碼

public static List<string> getOpenIssuesListByProject(string _projectName) 
    { 
     JiraSoapServiceService jiraSoapService = new JiraSoapServiceService(); 
     string token = jiraSoapService.login(DEFAULT_UN, DEFAULT_PW); 
     string[] keys = { getProjectKey(_projectName) }; 

     RemoteStatus[] statuses = jiraSoapService.getStatuses(token); 
     var desiredStatuses = statuses.Where(x => x.name == "Open" || x.name == "In Progress") 
      .Select(x=>x.id); 

     RemoteIssue[] AllIssues = jiraSoapService.getIssuesFromTextSearchWithProject(token, keys, "", 99); 
     IEnumerable<RemoteIssue> openIssues = AllIssues.Where(x=> 
      { 
       foreach (var v in desiredStatuses) 
       { 
        if (x.status == v) 
         return true; 
        else 
         return false; 
       } 
       return false; 
      }); 
     return openIssues.Select(x => x.key).ToList(); 
    } 

眼下這僅選擇「打開」的問題,而且似乎跳過那些「進行中」。

我的問題:首先,我爲什麼只獲得「開放」問題,其次是有更好的方法來做到這一點?

我首先獲取所有狀態的原因是該問題僅存儲該狀態ID,因此我獲取所有狀態,獲取匹配「打開」和「正在進行」的ID,然後將這些ID號與問題狀態字段。

回答

3
IEnumerable<RemoteIssue> openIssues = AllIssues.Where(x=> 
     { 
      foreach (var v in desiredStatuses) 
      { 
       if (x.status == v) 
        return true; 
      } 
      return false; 
     }); 

你的代碼只是檢查第一個狀態並返回false。你需要迭代所有的狀態,並且只有當它不在列表中時才返回false。

+0

謝謝,只是計算過,自己出去了。一直在尋找它45分鐘,並在我尋求幫助後2分鐘我想出來:) – Andy 2010-05-19 16:37:16

2

好了,你可以改變

IEnumerable<RemoteIssue> openIssues = AllIssues.Where(x=> 
{ 
    foreach (var v in desiredStatuses) 
    { 
     if (x.status == v) 
      return true; 
     else 
      return false; 
    } 
    return false; 
}); 

IEnumerable<RemoteIssue> openIssues = 
     AllIssues.Where(x=> desiredStatuses.Contains(x.status)); 

至於爲什麼你沒有得到二者的狀態 - 斯蒂芬給了我們答案。我上面的代碼更改也會解決這個問題。

+0

感謝代碼的縮寫行:) – Andy 2010-05-19 16:38:05

1

你只能得到一個狀態的原因是你在第一次檢查後總是退出循環。如果第一個項目不匹配,則不再檢查項目。如果除去在其他的回報,它會工作:

foreach (var v in desiredStatuses) { 
    if (x.status == v) { 
    return true; 
    } 
} 
return false; 

您應該確保實現期望狀態的集合,讓你不重新運行創建它每次你使用它的時候查詢:

var desiredStatuses = 
    statuses 
    .Where(x => x.name == "Open" || x.name == "In Progress") 
    .Select(x=>x.id) 
    .ToList(); 

如果有,你要檢查只有少數狀態,沒有必要讓它比這更有效。如果狀態很多,則可以將狀態變爲HashSet,並使用它的Contains方法,這比循環執行項目要快得多。

+0

感謝有關追加ToList(),以防止每次查詢信息。我仍然是一個新手,所以有點迷失在這:) – Andy 2010-05-19 20:18:04

0

代碼看起來我的權利,但也有辦法用更少編寫的代碼做...

關於:

眼下這僅選擇「打開」的問題,似乎跳過那些「正在進行」。

你能確認兩者都處於期望的狀態嗎?

此外,我假設RemoteIssue.status屬性確實是指狀態的id而不是名稱,因爲這是你正在比較它?

然後爲代碼,按馬丁·哈里斯的回答:我會用包含運營商,而不是你的內部循環...

0

更改此:

IEnumerable<RemoteIssue> openIssues = AllIssues.Where(x=> 
      { 
       foreach (var v in desiredStatuses) 
       { 
        if (x.status == v) 
         return true; 
        else 
         return false; 
       } 
       return false; 
      }); 

要這樣:

IEnumerable<RemoteIssue> openIssues = AllIssues.Where(x=> 
      { 
       foreach (var v in desiredStatuses) 
       { 
        if (x.status == v) 
         return true; 
        //else 
         //return false; 
       } 
       return false; 
      }); 
0

其他答案是正確的,但您可以使用直接Lambda而不是匿名代理來更簡潔地做到這一點。

IEnumerable<RemoteIssue> openIssues = AllIssues.Where(x=> 
     desiredStatuses.Contains(x.status) 

所以你的整個方法看起來像:

public static List<string> getOpenIssuesListByProject(string _projectName) 
{ 
    JiraSoapServiceService jiraSoapService = new JiraSoapServiceService(); 
    string token = jiraSoapService.login(DEFAULT_UN, DEFAULT_PW); 
    string[] keys = { getProjectKey(_projectName) }; 

    RemoteStatus[] statuses = jiraSoapService.getStatuses(token); 
    var desiredStatuses = statuses.Where(x => x.name == "Open" || x.name == "In Progress") 
     .Select(x=>x.id); 

    RemoteIssue[] AllIssues = jiraSoapService.getIssuesFromTextSearchWithProject(token, keys, "", 99); 
    IEnumerable<RemoteIssue> openIssues = AllIssues.Where(x => desiredStatuses.Contains(x.status)); 
    return openIssues.Select(x => x.key).ToList(); 
} 

這基本上發出SQL 「IN」 子句的等價物。所以,你的聲明全文:

SELECT <RemoteIssue> FROM AllIssues AS x WHERE x.status IN <desiredStatuses>