Powiedzmy, że mamy list.Where(p=>p.Number > n).Select(p=> p.Name).Where(n=> n.StartsWith(a)).ToList();
czy zostanie uruchomiony algorytm jednoprzebiegowy, czy będzie to 3 przejścia?Czy LINQ próbuje rozwiązać problemy za jednym razem?
Odpowiedz
Będzie budować listę w jednym przebiegu, ze względu na sposób, w jaki dane LINQ strumieni.
Na przykład, weźmy to:
var query = list.Where(p => p.Number > n);
To samo w sobie nie wygląda na dowolny z elementów listy. Zamiast tego zapamiętuje listę, na którą patrzysz, a kiedy zaczynasz iterować ponad query
, za każdym razem, gdy poprosisz o następny element, będzie on sprawdzał elementy listy po kolei, dopóki nie znajdzie dopasowania - następnie przestanie. Na przykład:
using (var iterator = query.GetEnumerator())
{
iterator.MoveNext(); // This will look for the first match
Console.WriteLine(iterator.Current);
iterator.MoveNext(); // This will continue from just after the first match
}
Każda z operacji działa w ten sposób - tak przez czas masz otrzymała:
var query = list.Where(...)
.Select(...)
.Where(...);
... jeśli poprosisz o pierwszej pozycji w ciągu query
, to będzie łańcuch kopii zapasowej (więc ostatni Where
zapyta o wynik Select
, który poprosi o wynik pierwszego Where
, który poprosi o listę) i będzie kontynuował aż do uzyskania wyniku. Wtedy, kiedy prosić o następnym punkcie, że poprosi wynik Select
do następnego elementu, itp
ToList
buduje List<T>
ze wszystkich przedmiotów w jego źródła, natychmiast - to chętny w tym sensie (zamiast innych operatorów, którzy są tutaj leniwi). Ale sama oryginalna lista będzie wciąż powtarzana tylko raz.
Dla część więcej szczegółów o tym, jak działa LINQ to Objects - w tym przykładowa implementacja - możesz przeczytać moją Edulinq blog series.
list
byłby iterowany tylko raz w tym kodzie, a nie 3 razy.
Oczywiście, jeśli chcesz sprawdzić, czy jakikolwiek arbitralny kwerendy iteracje po źródłach wielokrotnie jest to dość łatwe do przetestować eksperymentalnie, po prostu utwórz IEnumerable
że zgłasza wyjątek podczas próby iteracyjne to wiele razy:
public static IEnumerable<T> ThereCanBeOnlyOne<T>(this IEnumerable<T> source)
{
return new SingleEnumerable<T>(source);
}
private class SingleEnumerable<T> : IEnumerable<T>
{
private bool hasRun = false;
private IEnumerable<T> wrapped;
public SingleEnumerable(IEnumerable<T> wrapped)
{
this.wrapped = wrapped;
}
public IEnumerator<T> GetEnumerator()
{
if (hasRun)
throw new InvalidOperationException(
"Sequence cannot be enumerated multilpe times");
else
{
hasRun = true;
return wrapped.GetEnumerator();
}
}
IEnumerator IEnumerable.GetEnumerator()
{
return GetEnumerator();
}
}
teraz można po prostu napisać:
list.ThereCanBeOnlyOne()
.Where(p=>p.Number > n)
.Select(p=> p.Name)
.Where(n=> n.StartsWith(a))
.ToList();
Jeśli kod zgłasza wyjątek, próbowałeś iteracyjne listę o leżących u podstaw wielokrotnie. Jeśli nie, nie zrobiłeś tego.
- 1. Napraw wszystkie tabele za jednym razem
- 2. Jakiego rodzaju problemy mogą rozwiązać problemy map?
- 3. Jak otworzyć załącznik TFS WorkItem za jednym razem?
- 4. Jak odczytywać zawartość pliku do zmiennej za jednym razem?
- 5. Jak AirPrint wielu formaterów drukowania za jednym razem?
- 6. Laravel migrować - wiele migracji (plików) za jednym razem
- 7. Czy ktoś może nadużywać LINQ i rozwiązać tę zagadkę?
- 8. forep php w środku, aby rozwiązać problemy,
- 9. Jak rozwiązać problemy z ostrzeżeniem fileAttributesAtPath?
- 10. Jak rozwiązać problemy z mouseenter/mouseleave
- 11. Docker Ignoruje limits.conf (próbuje rozwiązać błąd "zbyt wielu otwartych plików")
- 12. Czy LINQ jest leniwy?
- 13. Problemy z porównaniem ciągów w LINQ
- 14. Problemy próbuje wygenerować aplikację z Android Kotlin Studio
- 15. Jak rozwiązać konflikt sortowania z Entity Framework?
- 16. x-ua za każdym razem nie działa
- 17. Czy można przestawić dane za pomocą LINQ?
- 18. Czy można manipulować listami za pomocą LINQ?
- 19. Problemy z typami zerowymi w funkcji LINQ
- 20. Jakie kroki podejmiesz, aby rozwiązać problemy z PHP cURL?
- 21. Czy mogę zaktualizować identyfikator właściciela kontaktu za pomocą LINQ?
- 22. Jak rozwiązać problemy z renderowaniem czcionek w mobilnym Safari?
- 23. Dzięki Vim Rails, możesz utworzyć nowy plik migracji i otworzyć go za jednym razem?
- 24. Jak zostawić wszystkie pokoje, do których podłączone jest gniazdo za jednym razem w pliku Node.js
- 25. Wstaw całą tabelę danych do bazy danych za jednym razem zamiast wiersz po wierszu?
- 26. Jak za jednym razem usunąć wszystkie elementy puste z ogólnej listy?
- 27. Twórz 2 listy za jednym razem podczas odczytu z pliku, pythonowo
- 28. Jaki jest najlepszy sposób, aby za jednym razem odczytać wszystkie dane z pliku tekstowego?
- 29. Jak rozwiązać problemy z wyciekiem pamięci ze słuchacza?
- 30. Utwórz nowy lub zaktualizuj istniejący podmiot za jednym razem, korzystając z wersji JPA
Załóżmy, że mamy egzamin państwowy i studenci są proszeni o rozwiązanie prostego zadania algorytmicznego, które można rozwiązać za pomocą C# LINQ w jednym ładnym, prostym zapytaniu. Jednak jeśli nie uda im się udowodnić na przebiegach w jednym przejściu, zostanie uznane za nieoptymalne rozwiązanie, a uczniowie otrzymają złe oceny. – Rella
Zauważ, że istnieje podobne pytanie dotyczące Linq2SQL: czy otrzymane zapytanie zostanie wykonane przy użyciu pojedynczej instrukcji 'SELECT'? W przypadku prostych zapytań, takich jak przykład, jeśli można je przekonwertować na zapytanie SQL, odpowiedź brzmi: tak. Ale niektóre [złożone] (http://stackoverflow.com/q/22816591/256431) [zapytania] (http://stackoverflow.com/q/12264751/256431) nie robią tego i nie wiem, czy każda gwarancja jest udzielana. –