Последовательность не содержит элементов при получении значения Null - PullRequest
1 голос
/ 24 февраля 2020

ExtraTime здесь представляет дополнительное время в баскетболе. Поскольку у большинства матчей нет дополнительного времени, ExtraTime будет иметь нулевое значение много раз.

Я искал другие вопросы и написал это, и это сработало. Код проверяет, есть ли дополнительное время, если не равен 0. И не учитывает 0 при расчете среднего.

OverTime = Math.Round(dtos.Select(p => (decimal)(p.ExtraTimeHomeTeamScore ?? 0)).Where(p => p != 0).Average(), 2),

Затем я попытался сделать что-то более сложное. Этот, чтобы проверить два разных типа данных и вычислить среднее из них. Также не включайте 0. По какой-то причине он возвращает ошибку последовательности.

 OverTime = Math.Round((decimal)(dtos.Where(p => p.DataType == 0).Select(p => p.ExtraTimeHomeTeamScore ?? 0).Where( p => p != 0).Average()
                        + dtos.Where(p => p.DataType == 1).Select(p => p.ExtraTimeAwayTeamScore ?? 0).Where(p => p != 0).Average()) / 2, 2)

Я пытался написать так же, как первый код. Что бы я ни делал, я не смог избавиться от Последовательность не содержит элементов Ошибка. Какая часть моего кода неверна и может быть улучшена?

Ответы [ 2 ]

2 голосов
/ 24 февраля 2020

Очевидно, что вы не можете Average ничего

Однако вы можете использовать Enumerable.DefaultIfEmpty

Возвращает элементы IEnumerable<T>, или однозначная коллекция по умолчанию, если последовательность пуста.

var result = dtos.Where(p => p.DataType == 0)
                 .Select(p => p.ExtraTimeHomeTeamScore ?? 0)
                 .Where( p => p != 0)
                 .DefaultIfEmpty(0)
                 .Average();
1 голос
/ 24 февраля 2020

Проверьте IEnumerable.Average документацию:

Исключения

ArgumentNullException

источник равен нулю.

InvalidOperationException

источник не содержит элементов.

Ваша проблема в том, что ваши фильтры (операторы where) ничего не возвращают. Так что, когда итоговые перечислимые элементы не содержат элементов, каково будет их среднее значение?

Я бы сделал что-то вроде этого:

var filteredDtos1 = dtos.Where(p => p.DataType == 0).Select(p => p.ExtraTimeHomeTeamScore ?? 0).Where( p => p != 0);
var filteredDtos2 = dtos.Where(p => p.DataType == 1).Select(p => p.ExtraTimeAwayTeamScore ?? 0).Where(p => p != 0).Average();

var avg1 = filteredDtos1.Count > 0 : filteredDtos1.Average ? //some default value probably 0;
var avg2 = filteredDtos2.Count > 0 : filteredDtos2.Average ? //some default value probably 0;

OverTime = Math.Round((decimal)(avg1 + avg2) / 2, 2);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...