2010-05-19 3 views
0

그래서 lambda 식과 linq를 함께 사용하기 시작했습니다. 나는 원하는 데이터를 얻으려고 애쓰는 동안 작은 문제가 생겼다. 이 메소드는,이는 "열기"이슈를 선택 현재 코드 람다 식과 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

2

글쎄, 당신은 당신이 두 상태를 받고되지 않는 이유에 대해서는

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

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

을 변경할 수 있습니다 - 스테판은 대답했다. 위의 코드 변경으로도 문제가 해결됩니다.

+0

코드의 축약 주셔서 감사합니다. :) – Andy

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

0
에 관한

적은 작성된 코드와 함께 할 수있는 방법이 있지만 코드는, 나에게 잘 보이는 ...

: 지금

이는 "열기"이슈를 선택하고 "진행 중"인 것은 건너 뛴 것처럼 보입니다.

두 가지 모두 desiredStatuses에 있는지 확인할 수 있습니까?

또한 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를 사용하여 좀 더 간결하게이 작업을 수행 할 수 있습니다. 이것은 기본적으로 절 "의"SQL의 등가을 방출

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(); 
} 

: 같은

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

그래서 모든 방법을 보일 것이다. 따라서 성명서는 다음과 같습니다 :

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