2016-06-16 3 views
1

Пожалуйста, помогите мне здесь. У меня есть запрос LinQ со многими условиями фильтра.LinQ Aggregate Error - Последовательность не содержит элементов

Ниже мой запрос:

var Aggregate = linqkb.Where(s => s.Status.Equals("Approved")).Select(s => s.Approver) 
    .Distinct() 
    .Aggregate((i, j) => i + ";" + j) 
    .Split(';') 
    .Distinct(); 

В некоторых случаях, я получаю сообщение об ошибке:

Error Message : Sequence contains no elements 
Stack Trace : at System.Linq.Enumerable.Aggregate[TSource](IEnumerable`1 source, Func`3 func) 

Я новичок в Linq. Пожалуйста, предложите.

Я гугл и попытался использовать **.DefaultIfEmpty()** до того Aggregator, как показано ниже:

var Aggregate = linqkb.Where(s => s.Status.Equals("Approved")).Select(s => s.Approver) 
    .Distinct() 
    .DefaultIfEmpty() 
    .Aggregate((i, j) => i + ";" + j) 
    .Split(';') 
    .Distinct(); 

Но это не работает.

Любые предложения?

+0

Что такое 'linqkb' и какими являются элементы этой последовательности? –

+0

Вы можете попытаться разделить вызовы и отладить промежуточные результаты. Возможно, нет элемента с 'Status =" Approved ". 'DefaultIfEmpty' предоставляет еще одну пустую последовательность afaik. –

+2

Почему вы присоединяетесь к ''; "', чтобы разделить его снова на следующей строке? Простейшим решением для исключения является предоставление начального значения 'Aggregate', т. Е.' Aggregate ("", (i, j) => i + ";" + j) '. – Lee

ответ

5

Aggregate использует первый элемент в последовательности, как аккумулятор, если ни один не предусмотрено. Это невозможно сделать, если в последовательности нет элементов, поэтому в этом случае генерируется исключение. Вы можете указать явное начальное значение т.е.

.Aggregate(string.Empty, (i, j) => i + ";" + j) 

Имейте в виду, что этот способ соединения строк неэффективно и создает много промежуточного мусора. Вы можете использовать string.Join, хотя непонятно, почему вы сразу разделили результат на ";" в следующей строке.

+0

Это сработало для меня, спасибо Ли! – user2598808

1

Ошибка в том, что говорит, нет элементов. linqkb.Where(s => s.Status.Equals("Approved")) возвращает пустой комплект. Агрегация не может работать над ним. Вы можете использовать Any() для проверки. Также ваше присоединение с ';', а затем делает Distinct, ничего не делает.

var Aggregate = linqkb.Where(s => s.Status.Equals("Approved"))                    .Select(s => s.Approver) 
    .Distinct(); 

if (!Aggreate.Any()) 
return ...; 
1

Прямое решение для выпуска выглядит следующим образом:

var Aggregate = linqkb 
    .Where(s => s.Status.Equals("Approved")) 
    .Select(s => s.Approver) 
    .Distinct() 
    .Aggregate(string.Empty, (i, j) => i + ";" + j) 
    .Split(';') 
    .Distinct(); 

т.е. вы должны использовать перегрузку агрегата с параметром семян.

Однако ваш запрос выглядит достаточно проводным. В случае, если вы просто хотите, различных значения поля утверждающего достаточно использовать следующую конструкцию:

var Aggregate = linqkb 
    .Where(s => s.Status.Equals("Approved")) 
    .Select(s => s.Approver) 
    .Distinct(); 

В случае, если утверждающее поле содержит значение, разделенное «;» и вы хотите извлечь их и получить отдельный список, то вы должны использовать:

var Aggregate = linqkb 
    .Where(s => s.Status.Equals("Approved")) 
    .SelectMany(s => s.Approver.Split(";")) 
    .Distinct(); 
Смежные вопросы