La séquence ne contient aucun élément?

131

J'utilise actuellement une seule requête à deux endroits pour obtenir une ligne à partir d'une base de données.

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

La requête est correcte lors de la récupération de la ligne dans laquelle placer des données dans les zones de texte, mais elle renvoie une erreur «La séquence ne contient aucun élément» lorsqu'elle est utilisée pour récupérer la ligne afin de la modifier et de la remettre dans la base de données. Je ne peux pas comprendre pourquoi il pourrait trouver une ligne appropriée dans une instance mais pas dans une autre.

(Utilisation d'ASP.NET MVC et LINQ)

David Basarab
la source
18
vous devez utiliser SingleOrDefault, il retournera null si aucun élément n'est retourné
Mahmoud Farahat
l'erreur indique qu'il ne trouve aucun élément dans dc.BlogPosts qui correspond à la valeur d'ID. Soit l'ID n'a aucune valeur, soit les éléments de votre liste contiennent cet élément. Utilisez SingleOrDefault ou FirstOrDefault, ceux-ci renverront un objet nul si aucun élément n'est trouvé plutôt qu'une erreur.
prd82

Réponses:

32

Mettez un point d'arrêt sur cette ligne, ou un Debug.Print avant, dans les deux cas et voyez ce que contient l'ID.

Ryan Lundy
la source
2
Je l'ai fait et j'ai constaté que, pour une raison quelconque, l'ID et la date sont passés comme null \ new (0000-0000) à partir de la page d'édition. La page est fortement typée comme BlogPost. Sur la page d'édition, je n'ai que des zones de texte pour le titre et le contenu, l'identifiant et la date ne sont pas du tout mis sur la page. Serait-ce la raison pour laquelle il les a passés comme null \ new?
2
D'où vous attendiez-vous que la pièce d'identité provienne?
Ryan Lundy
8
Avec le recul, je ne suis vraiment pas sûr> _ <Problème vraiment idiot.
367

À partir de " Correction d'une erreur LINQ: la séquence ne contient aucun élément ":

Lorsque vous obtenez l'erreur LINQ "La séquence ne contient aucun élément", c'est généralement parce que vous utilisez la commande First()ou Single()plutôt que FirstOrDefault()et SingleOrDefault().

Cela peut également être causé par les commandes suivantes:

  • FirstAsync()
  • SingleAsync()
  • Last()
  • LastAsync()
  • Max()
  • Min()
  • Average()
  • Aggregate()
Tony Kiernan
la source
3
Cela a résolu mon problème. Merci pour le lien!
CountMurphy
5
Parfait! ctx.Rosters.First(c => c.RosterAccess == accCode);<- cassé ctx.Rosters.FirstOrDefault(c => c.RosterAccess == accCode);<- TRAVAILLÉ
Ravi Ram
2
Dans mon cas, je faisais une Maxséquence vide
guzart
1
Alors maintenant, nous savons que chaque vote pèse (pour le moment) 31,25 livres.
B. Clay Shannon
2
Êtes-vous sûr que cela LastOrDefault()peut également déclencher cette erreur? Pourquoi ? Je pensais que le "OrDefault" était tout le point
Robouste
22

Veuillez utiliser

.FirstOrDefault()

car si dans la première ligne du résultat il n'y a pas d'informations, cette instruction va aux informations par défaut.

Josue Morales
la source
2
En cas d'appel asynchrone, utilisez .FirstOrDefaultAsync ();
Andrea Girardi
12

Eh bien, qu'est-ce qu'il y a IDici? En particulier, s'agit-il d'une variable locale? Il y a quelques problèmes de portée / capture, ce qui signifie qu'il peut être souhaitable d'utiliser une deuxième copie de variable, juste pour la requête:

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

Aussi; s'il s'agit de LINQ-to-SQL, dans la version actuelle, vous obtenez un comportement légèrement meilleur si vous utilisez le formulaire:

var id = ID;
BlogPost post = dc.BlogPosts.Single(p => p.BlogPostID == id);
Marc Gravell
la source
L'ID est un GUID passé en argument
10

Cela résoudra le problème,

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

En plus de tout ce qui a été dit, vous pouvez appeler DefaultIfEmpty()avant d'appeler Single(). Cela garantira que votre séquence contient quelque chose et évite ainsi l'exception InvalidOperationException "La séquence ne contient aucun élément". Par exemple:

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

J'ai eu une situation similaire sur une fonction qui calcule la moyenne.

Exemple:

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

Cas résolu:

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

Raison de l'erreur:

  1. La requête from p in dc.BlogPosts where p.BlogPostID == ID select prenvoie une séquence.

  2. Single() essaie de récupérer un élément de la séquence renvoyée à l'étape 1.

  3. Selon l'exception - La séquence retournée à l'étape1 ne contient aucun élément.

  4. Single () essaie de récupérer un élément de la séquence retournée à l'étape 1 qui ne contient aucun élément.

  5. Comme il Single()n'est pas en mesure d'extraire un seul élément de la séquence retournée à l'étape 1, il génère une erreur.

Réparer:

Assurez-vous que la requête (from p in dc.BlogPosts where p.BlogPostID == ID select p)

renvoie une séquence avec au moins un élément.

Siddarth Kanted
la source