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

131

В настоящее время я использую один запрос в двух местах, чтобы получить строку из базы данных.

BlogPost post = (from p in dc.BlogPosts
                 where p.BlogPostID == ID
                 select p).Single();

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

(Используя ASP.NET MVC и LINQ)

Давид Басараб
источник
18
вы должны использовать SingleOrDefault, он вернет null, если никакие элементы не возвращены
Махмуд Фарахат
ошибка говорит, что он не может найти в dc.BlogPosts элементы, соответствующие значению ID. Либо ID не имеет значения, либо элементы в вашем списке содержат этот элемент. Используйте SingleOrDefault или FirstOrDefault, они вернут нулевой объект, если элемент не найден, а не ошибка.
prd82

Ответы:

32

В обоих случаях поместите точку останова на эту строку или Debug.Print перед ней и посмотрите, какой идентификатор содержит.

Райан Ланди
источник
2
Сделал это и обнаружил, что по какой-то причине идентификатор и дата передаются как null \ new (0000-0000) со страницы редактирования. Страница строго типизирована как BlogPost. На странице редактирования у меня есть только текстовые поля для заголовка и содержимого, идентификатор и дата вообще не помещаются на страницу. Может ли это быть причиной того, что он передал их как null \ new?
2
Откуда вы ожидали получить удостоверение личности?
Райан Ланди,
8
Оглядываясь назад, я действительно не уверен> _ <Действительно глупая проблема.
368

Из « Исправление ошибки LINQ: последовательность не содержит элементов »:

Когда вы получаете ошибку LINQ «Последовательность не содержит элементов», это обычно происходит из-за того, что вы используете команду First()или, Single()а не FirstOrDefault()и SingleOrDefault().

Это также может быть вызвано следующими командами:

  • FirstAsync()
  • SingleAsync()
  • Last()
  • LastAsync()
  • Max()
  • Min()
  • Average()
  • Aggregate()
Тони Кирнан
источник
3
Это устранило мою проблему. Спасибо за ссылку!
CountMurphy 05
5
Отлично! ctx.Rosters.First(c => c.RosterAccess == accCode);<- сломано ctx.Rosters.FirstOrDefault(c => c.RosterAccess == accCode);<- РАБОТАЕТ
Рави Рам
2
В моем случае я делал Maxпустую последовательность
гузарт
1
Итак, теперь мы знаем, что каждое голосование "за" весит (на данный момент) 31,25 фунта.
B. Clay Shannon
2
Вы уверены, что LastOrDefault()это тоже может вызвать эту ошибку? Зачем ? Я думал, что «OrDefault» был
решающим
23

Пожалуйста, используйте

.FirstOrDefault()

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

Хосуэ Моралес
источник
2
В случае асинхронного вызова используйте .FirstOrDefaultAsync ();
Андреа Жирарди
12

Ну что IDздесь? В частности, это локальная переменная? Есть некоторые проблемы с областью / захватом, которые означают, что может быть желательно использовать вторую копию переменной только для запроса:

var id = ID;
BlogPost post = (from p in dc.BlogPosts
                 where p.BlogPostID == id
                 select p).Single();

Также; если это LINQ-to-SQL, то в текущей версии вы получите немного лучшее поведение, если воспользуетесь формой:

var id = ID;
BlogPost post = dc.BlogPosts.Single(p => p.BlogPostID == id);
Марк Гравелл
источник
ID - это GUID, переданный в качестве аргумента
10

Это решит проблему,

var blogPosts = (from p in dc.BlogPosts
             where p.BlogPostID == ID
             select p);
if(blogPosts.Any())
{
  var post = post.Single();
}
Диганта Кумар
источник
8

Помимо всего прочего, вы можете позвонить DefaultIfEmpty()перед тем, как позвонить Single(). Это гарантирует, что ваша последовательность что-то содержит, и тем самым предотвратит InvalidOperationException «Последовательность не содержит элементов». Например:

BlogPost post = (from p in dc.BlogPosts
                 where p.BlogPostID == ID
                 select p).DefaultIfEmpty().Single();
bryc3m0nk3y
источник
2

У меня была аналогичная ситуация с функцией, вычисляющей среднее значение.

Пример:

ws.Cells[lastRow, startingmonths].Value = lstMediaValues.Average();

Дело решено:

ws.Cells[lastRow, startingmonths].Value = lstMediaValues.Count == 0 ? 0 : lstMediaValues.Average();
Михай Кристиан
источник
1

Причина ошибки:

  1. Запрос from p in dc.BlogPosts where p.BlogPostID == ID select pвозвращает последовательность.

  2. Single() пытается получить элемент из последовательности, возвращенной на шаге 1.

  3. Согласно исключению - последовательность, возвращенная на шаге 1, не содержит элементов.

  4. Single () пытается получить элемент из последовательности, возвращенной на шаге 1, которая не содержит элементов.

  5. Поскольку Single()не может получить ни одного элемента из последовательности, возвращенной на шаге 1, возникает ошибка.

Fix:

Убедитесь, что запрос (from p in dc.BlogPosts where p.BlogPostID == ID select p)

возвращает последовательность как минимум с одним элементом.

Сиддарт Канант
источник