[英]Using lambda expressions and linq
因此,我剛剛開始使用linq以及使用lambda表達式。 嘗試獲取一些我想要的數據時,我遇到了一個小小的麻煩。 此方法應返回從Jira打開或正在進行的所有項目的列表
這是代碼
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號與問題狀態字段匹配。
IEnumerable<RemoteIssue> openIssues = AllIssues.Where(x=>
{
foreach (var v in desiredStatuses)
{
if (x.status == v)
return true;
}
return false;
});
您擁有的代碼僅檢查第一個狀態並返回false。 您需要迭代所有狀態並僅在根本不在列表中時返回false。
好吧,你可以改變
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));
至於為什么你沒有同時獲得兩種身份-斯蒂芬回答了。 我上面的代碼更改也將解決該問題。
之所以只得到一個狀態,是因為您總是在第一次檢查后就退出循環。 如果第一個項目不匹配,則不會檢查更多項目。 如果您刪除else中的收益,它將起作用:
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
方法,該方法比遍歷項目快得多。
該代碼對我來說似乎正確,盡管有許多方法可以減少編寫的代碼。
關於:
現在,這僅選擇“打開”的問題,似乎跳過了“進行中”的問題。
您能否確定兩者都處於期望狀態?
我還假設RemoteIssue.status屬性確實是指狀態的ID,而不是名稱,因為這就是您要與之比較的內容?
然后根據馬丁·哈里斯(Martin Harris)的答案編寫代碼:我將使用Contains運算符,而不是您的內部循環...
更改此:
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;
});
其他答案是正確的,但是您可以使用簡單的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>
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.