La sequenza non contiene elementi?


131

Attualmente sto usando una singola query in due punti per ottenere una riga da un database.

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

La query va bene quando si recupera la riga per inserire i dati nelle caselle di testo, ma restituisce un errore "La sequenza non contiene elementi" quando viene utilizzata per recuperare la riga per modificarla e reinserirla nel database. Non riesco a capire perché potrebbe trovare una riga appropriata in un'istanza ma non in un'altra.

(Utilizzando ASP.NET MVC e LINQ)


18
devi usare SingleOrDefault, restituirà null se non viene restituito alcun articolo
Mahmoud Farahat,

l'errore sta dicendo che non è possibile trovare elementi in dc.BlogPosts che corrispondono al valore di ID. L'ID non ha valore o gli elementi nell'elenco contengono quell'elemento. Usa SingleOrDefault o FirstOrDefault, restituiranno un oggetto null se non viene trovato alcun elemento anziché un errore.
prd82

Risposte:


32

Inserisci un punto di interruzione su quella linea o un Debug.Print prima di esso, in entrambi i casi e vedi quale ID contiene.


2
L'ho fatto e ho scoperto che, per qualche motivo, l'ID e la data vengono passati come null \ new (0000-0000) dalla pagina di modifica. La pagina è fortemente tipizzata come BlogPost. Nella pagina di modifica, ho solo caselle di testo per il titolo e il contenuto, l'ID e la data non sono affatto inseriti nella pagina. Potrebbe essere questo il motivo per cui li passa come null \ new?

2
Da dove ti aspettavi che arrivasse l'ID?
Ryan Lundy,

8
A posteriori, non sono proprio sicuro> _ <Problema sciocco davvero.

367

Da " Correzione dell'errore LINQ: la sequenza non contiene elementi ":

Quando viene visualizzato l'errore LINQ "La sequenza non contiene elementi", ciò si verifica in genere perché si utilizza il comando First()o Single()anziché FirstOrDefault()e SingleOrDefault().

Ciò può essere causato anche dai seguenti comandi:

  • FirstAsync()
  • SingleAsync()
  • Last()
  • LastAsync()
  • Max()
  • Min()
  • Average()
  • Aggregate()

3
Questo risolto il mio problema. Grazie per il link!
CountMurphy,

5
Perfetto! ctx.Rosters.First(c => c.RosterAccess == accCode);<- rotto ctx.Rosters.FirstOrDefault(c => c.RosterAccess == accCode);<- LAVORATO
Ravi Ram

2
Nel mio caso stavo facendo una Maxsequenza più che vuota
guzart,

1
Quindi ora sappiamo che ogni voto positivo pesa (al momento) 31,25 sterline.
B. Clay Shannon,

2
Sei sicuro che LastOrDefault()possa anche innescare quell'errore? Perché ? Pensavo che "OrDefault" fosse
perfetto

22

Si prega di utilizzare

.FirstOrDefault()

perché se nella prima riga del risultato non ci sono informazioni questa istruzione passa alle informazioni predefinite.


2
In caso di chiamata asincrona usare .FirstOrDefaultAsync ();
Andrea Girardi,

12

Bene, cosa c'è IDqui? In particolare, è una variabile locale? Esistono alcuni problemi di ambito / acquisizione, il che significa che potrebbe essere desiderabile utilizzare una seconda copia variabile, solo per la query:

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

Anche; se si tratta di LINQ-to-SQL, nella versione corrente si ottiene un comportamento leggermente migliore se si utilizza il modulo:

var id = ID;
BlogPost post = dc.BlogPosts.Single(p => p.BlogPostID == id);

L'ID è un GUID trasmesso come argomento

10

Questo risolverà il problema,

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

8

Oltre a tutto ciò che è stato detto, puoi chiamare DefaultIfEmpty()prima di chiamare Single(). Questo assicurerà che la sequenza contenga qualcosa e quindi media la InvalidOperationException "La sequenza non contiene elementi". Per esempio:

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

2

Ho avuto una situazione simile su una funzione che calcola la media.

Esempio:

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

Caso risolto:

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

1

Motivo dell'errore:

  1. La query from p in dc.BlogPosts where p.BlogPostID == ID select prestituisce una sequenza.

  2. Single() tenta di recuperare un elemento dalla sequenza restituita nel passaggio 1.

  3. Come per l'eccezione : la sequenza restituita nel passaggio 1 non contiene elementi.

  4. Single () tenta di recuperare un elemento dalla sequenza restituita nel passaggio 1 che non contiene elementi.

  5. Poiché Single()non è in grado di recuperare un singolo elemento dalla sequenza restituita nel passaggio 1, genera un errore.

fix:

Assicurati che la query (from p in dc.BlogPosts where p.BlogPostID == ID select p)

restituisce una sequenza con almeno un elemento.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.