0

ですから、私はlinqとラムダ式の使用を始めたばかりです。必要なデータを取得しようとしているときに、小さな問題が発生しました。このメソッドは、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番号を問題のステータスフィールドに一致させるためです。 。

4

6 に答える 6

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

あなたが持っていたコードは、最初の状態をチェックし、falseを返すだけでした。すべての状態を繰り返し、リストにまったく含まれていない場合にのみfalseを返す必要があります。

于 2010-05-19T16:32:04.673 に答える
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));

両方のステータスが得られない理由については、Stephanが答えています。上記の私のコード変更は、その問題も修正します。

于 2010-05-19T16:30:16.863 に答える
1

ステータスが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

于 2010-05-19T16:33:59.273 に答える
0

他の答えは正しいですが、匿名のデリゲートの代わりにストレートラムダを使用してこれをもう少し簡潔に行うことができます。

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>
于 2010-05-19T17:36:46.970 に答える
0

コードは私には正しく見えますが、より少ないコードでそれを行う方法があります...

それにかんする:

現在、これは「未解決」の問題のみを選択し、「進行中」の問題をスキップしているようです。

ただし、両方がdesiredStatussにあることを確認できますか?

また、RemoteIssue.statusプロパティは、名前ではなくステータスのIDを実際に参照していると思います。これは、それを比較しているものなのでしょうか。

次に、コードについては、Martin Harrisの回答に従って、内側のループではなく、Contains演算子を使用します...

于 2010-05-19T16:34:20.553 に答える
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;
            });
于 2010-05-19T16:38:51.227 に答える