Последовательность не содержит элементов в LINQ

В показанном здесь коде я получаю ошибку в LINQ:

Последовательность не содержит элементов

Когда столбец reason содержит данные, возникает это исключение. Подскажите пожалуйста, как обработать это исключение.

Код:

if (StudentDetails.rows
                  .Where(c => string.IsNullOrEmpty(c.reason) && !c.leave) 
                  .Min(c => c.joiningdate) < DateTime.UtcNow.AddDays(-180))
    return true;

Подразумевается, что нет строк, в которых «разум» имеет значение null, а «leaveL» — ложь. Как вы думаете, они есть?

Tim Roberts 12.07.2024 06:39

@TimRoberts, когда причина содержит данные, а значение отпуска ложно, выдается ошибка

user2432361 12.07.2024 06:54

Во-первых, это не ответ на вопрос, который вам задали. Если вы имеете в виду, что, по вашему мнению, они существуют, то ответ на вопрос — «да», и именно это вам и следовало сказать. Если вы на самом деле имеете в виду что-то другое, уточните, что это такое.

jmcilhinney 12.07.2024 07:15

Почти наверняка нет данных, соответствующих этим критериям, и вы просто думаете, что они есть. Чтобы узнать это, нужно проверить это, что вы уже должны были сделать. Используйте обычный цикл для всех данных и поместите внутри блок if, который проверяет те же критерии. Затем вы можете поставить точку останова внутри этого блока и посмотреть, будет ли он достигнут. Если это не так, то соответствующих данных нет, и поэтому вы получаете сообщение об ошибке, сообщающее вам об этом. Если он попадет, значит, ваша система сломана, потому что в этом случае LINQ должен работать.

jmcilhinney 12.07.2024 07:17

Ваше предложение Where выбирает все строки, где «причина» пуста, а «оставить» имеет значение false. Если «причина» всегда имеет данные, то КОНЕЧНО, результирующая последовательность не будет содержать элементов.

Tim Roberts 12.07.2024 08:08
Стоит ли изучать PHP в 2023-2024 годах?
Стоит ли изучать PHP в 2023-2024 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
5
83
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

В показанном здесь коде я получаю ошибку в LINQ:

Последовательность не содержит элементов

На основе вашего общего фрагмента кода и описания я попытался воспроизвести вашу проблему и смог смоделировать возникшую ошибку. Ниже приводится ссылка для вас.

Когда столбец причины содержит данные, возникает это исключение. Подскажите пожалуйста, как обработать это исключение.

Согласно сообщению об ошибке, которое указывает, что это может произойти, если все элементы в StudentDetails.rows имеют non-null reason или leave is true, что приводит к пустой последовательности для работы метода Min.

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

Чтобы преодолеть исключение, вам следует сначала проверить, есть ли какие-либо элементы в отфильтрованной последовательности, прежде чем вызывать Min. Вы можете использовать метод Любой в Linq, чтобы убедиться, что последовательность не пуста.

Скажем, у меня есть следующий набор данных:

private readonly List<Student> _studentDetails = new List<Student>
{
    new Student { reason = "Medical", leave = true, joiningdate = new DateTime(2023, 1, 10) },
    new Student { reason = "Personal", leave = true, joiningdate = new DateTime(2022, 2, 15) },
    new Student { reason = "Vacation", leave = true, joiningdate = new DateTime(2021, 3, 20) },
    new Student { reason = "Disciplinary", leave = false, joiningdate = new DateTime(2023, 4, 1) },
    new Student { reason = "Health", leave = true, joiningdate = new DateTime(2021, 5, 30) },
};

Как вы заметили выше, набор данных не выполнил бы условие, в этом случае я бы изменил запрос следующим образом:

var filteredRows = _studentDetails
    .Where(c => string.IsNullOrEmpty(c.reason) && !c.leave);

if (filteredRows.Any() && filteredRows.Min(c => c.joiningdate) < DateTime.UtcNow.AddDays(-180))
{
    return Ok(true);
}

Итак, в filteredRows сначала присваивается результат метода Where, фильтрующего строки на основе ваших условий. Затем метод Any используется для проверки того, содержит ли filteredRows какие-либо элементы. Только если filteredRows не пусто, вызывается метод Min для поиска минимума joiningdate, и исключение больше не выдается.

Выход:

Примечание. Пожалуйста, обратитесь к этому официальному документу, если вам нужна дополнительная информация.

Ошибка связана с функцией Min. Он выдает исключение, если источник не содержит элементов. Ниже приводится краткое описание функции Min:

//
// Summary:
//     Returns the minimum value in a sequence of System.Int32 values.
//
// Parameters:
//   source:
//     A sequence of System.Int32 values to determine the minimum value of.
//
// Returns:
//     The minimum value in the sequence.
//
// Exceptions:
//   T:System.ArgumentNullException:
//     source is null.
//
//   T:System.InvalidOperationException:
//     source contains no elements.
[__DynamicallyInvokable]
public static int Min(this IEnumerable<int> source)

Если во всех строках столбца reason есть данные, ваша функция Where вернет пустое перечислимое. Это потому, что IsNullOrEmpty — ваше первое условие. А поскольку вы используете операцию &&, выражение всегда будет иметь значение false, если столбец причины не равен нулю или не пуст.

Вы можете решить эту проблему, используя DefaultIfEmpty, как объяснил Кристофер Летте в этом ответе Stackoverflow https://stackoverflow.com/a/2167461/24889207. Для ссылочных типов в C# значение по умолчанию — null. Итак, вам, возможно, придется с этим справиться.

Кстати, вы можете напрямую вернуть результат Min вместо того, чтобы заключать его в условие if и возвращать true.

Пример:

return StudentDetails.rows
    .Where(c => string.IsNullOrEmpty(c.reason) && !c.leave)
    .DefaultIfEmpty()
    .Min(c => c?.joiningdate ?? DateTime.UtcNow) < DateTime.UtcNow.AddDays(-180)

Min выдает исключение, если элементов нет, но только если T является типом значения, не допускающим значения NULL. Таким образом, вы можете просто привести к нулю.

if (StudentDetails.rows
    .Where(c => !c.leave && string.IsNullOrEmpty(c.reason)) 
    .Min(c => (DateTime?) c.joiningdate) < DateTime.UtcNow.AddDays(-180))
    return true;

Другие вопросы по теме