2010-05-19 2 views
0

Итак, я только начал работать с linq, а также с помощью лямбда-выражений. Я столкнулся с небольшой икотой, пытаясь получить некоторые данные, которые я хочу. Этот метод должен возвращать список всех проектов, которые открыты или в процессе из JiraИспользование лямбда-выражений и 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(); 
    } 

Сейчас это выбрать только вопросы, которые являются «Open», и, кажется, чтобы пропустить те, которые "В ходе выполнения".

Мой вопрос: во-первых, почему я только получаю «открытые» проблемы, а во-вторых, лучший способ сделать это?

Причина, по которой я получаю все статусы в первую очередь, заключается в том, что проблема только сохраняет этот идентификатор статусов, поэтому я получаю все статусы, получаю идентификаторы, которые соответствуют «Open» и «In Progress», а затем соответствуют этим идентификационным номерам поле статуса проблем.

ответ

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=> 
{ 
    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

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

Код смотрит прямо на меня, хотя есть способы, чтобы сделать это с меньшими затратами написанного кодом ...

Относительно:

Правых ныне это только выбрать вопросы, имеющие «Открыть», и кажется, пропускают те, которые находятся в процессе.

Можете ли вы подтвердить, что оба находятся в желаемых состояниях?

Также я предполагаю, что свойство RemoteIssue.status действительно ссылается на идентификатор статуса, а не на имя, так как это вы его сравниваете?

Тогда для кода, как в ответ Мартин Харрис: Я хотел бы использовать Содержит оператора, а не на внутренней петле ...

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

Другие ответы правильные, но вы можете сделать это немного более кратко с прямой Лямбдой вместо анонимного делегата.

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 "В" п. Так что ваше утверждение гласит:

SELECT <RemoteIssue> FROM AllIssues AS x WHERE x.status IN <desiredStatuses> 
Смежные вопросы