所以我刚开始使用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号匹配到问题状态字段。
答案 0 :(得分:3)
IEnumerable<RemoteIssue> openIssues = AllIssues.Where(x=>
{
foreach (var v in desiredStatuses)
{
if (x.status == v)
return true;
}
return false;
});
您所拥有的代码只检查第一个状态并返回false。您需要迭代所有状态,并且只有在它根本不在列表中时才返回false。
答案 1 :(得分: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));
至于为什么你没有得到这两种状态 - 斯蒂芬已经回答了这个问题。我上面的代码更改也将解决这个问题。
答案 2 :(得分:1)
您只获得一个状态的原因是您在第一次检查后总是退出循环。如果第一个项目不匹配,则不再检查项目。如果你在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
方法,这比循环遍历项目快得多。
答案 3 :(得分:0)
代码对我来说是正确的,尽管有很多方法可以用较少的代码编写代码......
关于:
现在这只选择“开放”的问题,似乎跳过“正在进行中”的问题。
你能否确认两者都在所需的状态?
另外我假设RemoteIssue.status属性确实是指状态的id而不是name,因为那是你要比较它的东西?
然后对于代码,根据Martin Harris的回答:我会使用Contains运算符而不是你的内循环......
答案 4 :(得分: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;
});
答案 5 :(得分: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>