A sequência não contém elementos?

131

Atualmente, estou usando uma única consulta em dois lugares para obter uma linha de um banco de dados.

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

A consulta é boa ao recuperar a linha para inserir dados nas caixas de texto, mas retorna um erro "Sequência não contém elementos" quando usada para recuperar a linha para editá-la e colocá-la novamente no banco de dados. Não consigo entender por que ele pode encontrar uma linha apropriada em uma instância, mas não em outra.

(Usando o ASP.NET MVC e LINQ)

David Basarab
fonte
18
você tem que usar SingleOrDefault, ele retornará nulo se nenhum item voltou
Mahmoud Farahat
o erro está dizendo que não é possível encontrar nenhum item no dc.BlogPosts que corresponda ao valor do ID. O ID não tem valor ou os itens da sua lista contêm esse item. Use SingleOrDefault ou FirstOrDefault, eles retornarão um objeto nulo se nenhum item for encontrado, em vez de erro.
prd82 9/03

Respostas:

32

Coloque um ponto de interrupção nessa linha ou um Debug.Print antes dele, nos dois casos, e veja qual ID contém.

Ryan Lundy
fonte
2
Fiz isso e constatou que, por algum motivo, o ID e a data estão sendo passados ​​como nulos \ new (0000-0000) na página de edição. A página está fortemente digitada como BlogPost. Na página de edição, só tenho caixas de texto para o título e o conteúdo, o ID e a data não são colocados na página. Poderia ser esse o motivo para transmiti-los como nulos \ novos?
2
De onde você esperava que o ID viesse?
22611 Ryan Lundy
8
Em retrospectiva, eu realmente não tenho certeza> _ <Problema bobo realmente.
367

Em " Corrigindo o erro LINQ: a sequência não contém elementos ":

Quando você obtém o erro LINQ "Sequência não contém elementos", isso geralmente ocorre porque você está usando o comando First()ou em Single()vez de FirstOrDefault()e SingleOrDefault().

Isso também pode ser causado pelos seguintes comandos:

  • FirstAsync()
  • SingleAsync()
  • Last()
  • LastAsync()
  • Max()
  • Min()
  • Average()
  • Aggregate()
Tony Kiernan
fonte
3
Isso corrigiu meu problema. Obrigado pelo link!
CountMurphy
5
Perfeito! ctx.Rosters.First(c => c.RosterAccess == accCode);<- quebrado ctx.Rosters.FirstOrDefault(c => c.RosterAccess == accCode);<- TRABALHADO
Ravi Ram
2
No meu caso eu estava fazendo um Maxsobre uma seqüência vazia
guzart
1
Então agora sabemos que cada voto em cima pesa (no momento) 31,25 libras.
B. Clay Shannon
2
Tem certeza de que LastOrDefault()também pode acionar esse erro? Por quê ? Eu pensei que o "OrDefault" era o ponto
Robouste
22

Por favor, use

.FirstOrDefault()

porque se na primeira linha do resultado não houver informações, esta instrução passará para as informações padrão.

Josue Morales
fonte
2
No caso de chamada assíncrona, use .FirstOrDefaultAsync ();
Andrea Girardi
12

Bem, o que está IDaqui? Em particular, é uma variável local? Existem alguns problemas de escopo / captura, o que significa que pode ser desejável usar uma segunda cópia variável, apenas para a consulta:

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

Além disso; se for LINQ-to-SQL, na versão atual, você terá um comportamento um pouco melhor se usar o formulário:

var id = ID;
BlogPost post = dc.BlogPosts.Single(p => p.BlogPostID == id);
Marc Gravell
fonte
ID é um GUID passado como um argumento
10

Isto resolverá o problema,

var blogPosts = (from p in dc.BlogPosts
             where p.BlogPostID == ID
             select p);
if(blogPosts.Any())
{
  var post = post.Single();
}
Diganta Kumar
fonte
8

Além de tudo o que foi dito, você pode ligar DefaultIfEmpty()antes de ligar Single(). Isso garantirá que sua sequência contenha algo e, assim, evite a InvalidOperationException "Sequência não contém elementos". Por exemplo:

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

Eu tive uma situação semelhante em uma função que calcula a média.

Exemplo:

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

Caso resolvido:

ws.Cells[lastRow, startingmonths].Value = lstMediaValues.Count == 0 ? 0 : lstMediaValues.Average();
Mihai Cristian
fonte
1

Motivo do erro:

  1. A consulta from p in dc.BlogPosts where p.BlogPostID == ID select pretorna uma sequência.

  2. Single() tenta recuperar um elemento da sequência retornada na etapa1.

  3. Conforme a exceção - A sequência retornada na etapa 1 não contém elementos.

  4. Single () tenta recuperar um elemento da sequência retornada na etapa 1 que não contém elementos.

  5. Como Single()não é possível buscar um único elemento da sequência retornada na etapa 1, gera um erro.

Consertar:

Verifique se a consulta (from p in dc.BlogPosts where p.BlogPostID == ID select p)

retorna uma sequência com pelo menos um elemento.

Siddarth Kanted
fonte