Sekwencja nie zawiera żadnych elementów?

131

Obecnie używam jednego zapytania w dwóch miejscach, aby pobrać wiersz z bazy danych.

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

Zapytanie działa poprawnie podczas pobierania wiersza w celu umieszczenia danych w polach tekstowych, ale zwraca błąd „Sekwencja nie zawiera żadnych elementów”, gdy jest używane do pobrania wiersza w celu edycji i umieszczenia z powrotem w bazie danych. Nie rozumiem, dlaczego może znaleźć odpowiedni wiersz w jednym przypadku, a w innym nie.

(Korzystanie z ASP.NET MVC i LINQ)

David Basarab
źródło
18
musisz użyć SingleOrDefault, zwróci wartość null, jeśli żadne elementy nie zostaną zwrócone
Mahmoud Farahat
błąd mówi, że nie może znaleźć żadnych pozycji w dc.BlogPosts, które pasują do wartości ID. Identyfikator nie ma wartości lub pozycje na liście zawierają ten element. Użyj SingleOrDefault lub FirstOrDefault, te zwrócą obiekt pusty, jeśli nie zostanie znaleziony żaden element, a nie błąd.
prd82

Odpowiedzi:

32

Umieść punkt przerwania w tym wierszu lub przed nim Debug.Print, w obu przypadkach i zobacz, jaki identyfikator zawiera.

Ryan Lundy
źródło
2
Zrobiłem to i odkryłem, że z jakiegoś powodu identyfikator i data są przekazywane jako null \ new (0000-0000) ze strony edycji. Strona jest silnie wpisana jako BlogPost. Na stronie edycji mam tylko pola tekstowe dla tytułu i treści, identyfikator i data nie są w ogóle umieszczane na stronie. Czy to może być powód, dla którego uznaje je za null \ new?
2
Skąd spodziewałeś się, że ma pochodzić identyfikator?
Ryan Lundy
8
Z perspektywy czasu naprawdę nie jestem pewien> _ <Naprawdę głupi problem.
367

Od „ Naprawianie błędu LINQ: sekwencja nie zawiera żadnych elementów ”:

Gdy pojawi się błąd LINQ „Sekwencja nie zawiera żadnych elementów”, zwykle jest to spowodowane użyciem polecenia First()lub Single()zamiast FirstOrDefault()i SingleOrDefault().

Może to być również spowodowane następującymi poleceniami:

  • FirstAsync()
  • SingleAsync()
  • Last()
  • LastAsync()
  • Max()
  • Min()
  • Average()
  • Aggregate()
Tony Kiernan
źródło
3
To rozwiązało mój problem. Dzięki za link!
CountMurphy,
5
Idealny! ctx.Rosters.First(c => c.RosterAccess == accCode);<- zepsuty ctx.Rosters.FirstOrDefault(c => c.RosterAccess == accCode);<- PRACOWANY
Ravi Ram
2
W moim przypadku robiłem Maxponad pustą sekwencję
guzart
1
Więc teraz wiemy, że każdy głos pozytywny waży (w tej chwili) 31,25 funta.
B. Clay Shannon
2
Czy na pewno LastOrDefault()może to również wywołać ten błąd? Czemu ? Myślałem, że chodzi o "OrDefault"
Robouste
22

Proszę użyć

.FirstOrDefault()

ponieważ jeśli w pierwszym wierszu wyniku nie ma informacji to instrukcja przechodzi do informacji domyślnych.

Josue Morales
źródło
2
W przypadku wywołania asynchronicznego użyj funkcji .FirstOrDefaultAsync ();
Andrea Girardi
12

Cóż, co IDtu jest ? W szczególności czy jest to zmienna lokalna? Istnieją pewne problemy z zasięgiem / przechwytywaniem, co oznacza, że ​​może być pożądane użycie drugiej kopii zmiennej, tylko dla zapytania:

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

Również; jeśli to jest LINQ-to-SQL, to w aktualnej wersji uzyskujesz nieco lepsze zachowanie, jeśli używasz formularza:

var id = ID;
BlogPost post = dc.BlogPosts.Single(p => p.BlogPostID == id);
Marc Gravell
źródło
ID to identyfikator GUID przekazany jako argument
10

To rozwiąże problem,

var blogPosts = (from p in dc.BlogPosts
             where p.BlogPostID == ID
             select p);
if(blogPosts.Any())
{
  var post = post.Single();
}
Diganta Kumar
źródło
8

Oprócz wszystkiego innego, co zostało powiedziane, możesz zadzwonić, DefaultIfEmpty()zanim zadzwonisz Single(). Zapewni to, że sekwencja zawiera coś, a tym samym uniknie wyjątku InvalidOperationException „Sekwencja nie zawiera żadnych elementów”. Na przykład:

BlogPost post = (from p in dc.BlogPosts
                 where p.BlogPostID == ID
                 select p).DefaultIfEmpty().Single();
bryc3m0nk3y
źródło
2

Miałem podobną sytuację w przypadku funkcji obliczającej średnią.

Przykład:

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

Sprawa została rozwiązana:

ws.Cells[lastRow, startingmonths].Value = lstMediaValues.Count == 0 ? 0 : lstMediaValues.Average();
Mihai Cristian
źródło
1

Przyczyna błędu:

  1. Zapytanie from p in dc.BlogPosts where p.BlogPostID == ID select pzwraca sekwencję.

  2. Single() próbuje pobrać element z sekwencji zwróconej w kroku 1.

  3. Zgodnie z wyjątkiem - sekwencja zwrócona w kroku 1 nie zawiera żadnych elementów.

  4. Single () próbuje pobrać element z sekwencji zwróconej w kroku 1, który nie zawiera żadnych elementów.

  5. Ponieważ Single()nie jest w stanie pobrać pojedynczego elementu z sekwencji zwróconej w kroku 1, zgłasza błąd.

Naprawić:

Upewnij się, że zapytanie (from p in dc.BlogPosts where p.BlogPostID == ID select p)

zwraca sekwencję z co najmniej jednym elementem.

Siddarth Kanted
źródło