2012-03-24 2 views
26

У меня есть следующий запрос Linq:Как обрабатывать нули в LINQ при использовании Min или Max?

result.Partials.Where(o => o.IsPositive).Min(o => o.Result) 

я получаю исключение при result.Partials.Where (о => o.IsPositive) не содержит элементов. Есть ли элегантный способ справиться с этим иначе, чем разделить операцию на две части и проверить на нуль? У меня есть класс, полный таких операций, как этот.

EDIT: вопрос связан с LINQ to Objects.

Это исключение я получаю (в переводе она говорит: последовательность пуста):

enter image description here

+0

Какое исключение вы получаете? По моему опыту, если 'Partials' пуст, вы должны получить 0. –

+0

ваша трассировка стека имеет вызов' Min() 'not' Sum() '. Что такое «результат»? – Jon

+0

Извините. Мой плохой, операция Min и Max not Sum. Еще раз извините. Редактирование вопроса. –

ответ

53

краткое обобщенное расчет из Min

var min = result.Partials.Where(o => o.IsPositive).Min(o => o.Result); 

Это ваш случай: если нет подходящих элементов, то Min вызов сгенерирует исключение (InvalidOperationException).

var min = result.Partials.Where(o => o.IsPositive) 
          .Select(o => o.Result) 
          .DefaultIfEmpty().Min(); 

DefaultIfEmpty создаст перечисление над 0 элемента, когда нет элементов в списке. Как вы знаете, что 0 - это Min или 0 означает список без элементов?

var min = result.Partials.Where(o => o.IsPositive) 
          .Min(o => (decimal?)o.Result); 

Здесь min является либо нулевым (defaul(decimal?)), либо фактическим минимальным. Таким образом, потребитель этого результата будет знать, что если результат равен нулю, то в списке не было элементов, а когда результат был десятичным, тогда список имел некоторые элементы, а Min из этих элементов - это значение.

Однако, если это не имеет значения, то можно назвать min.GetValueOrDefault(0).

6

Вы не можете использовать Min (или Max), если последовательность пуста. Если этого не должно быть, у вас другая проблема с тем, как вы определяете result. В противном случае, вы должны проверить, если последовательность пуста и обрабатывать соответствующим образом, например:

var query = result.Partials.Where(o => o.IsPositve); 
min = query.Any() ? query.Min(o => o.Result) : 0; // insert a different "default" value of your choice...  
+0

это сделает 2 запроса. но это можно сделать с помощью одного. – maxlego

8

Вы можете использовать метод DefaultIfEmpty, чтобы обеспечить сбор, по меньшей мере 1 пункт:

result.Partials.Where(o => o.IsPositive).Select(o => o.Result).DefaultIfEmpty().Min(); 
+0

..что, если значение по умолчанию равно null? –

+0

@RitchMelton: Я верю, что Min вернет null. –

+0

Я уверен, что вызов 'o.Result' с нулевым элементом вызывает исключение. –

Смежные вопросы