Powiedz, że mam IQueryable<Car> cars
.
Iteruję to takie jak:
foreach (Car c in cars)
{
c.Doors = 2;
}
Dlaczego c.Doors
zawiera oryginalną wartość po foreach, a nie zmienioną wartość?
Z góry dziękuję
2 odpowiedzi
Wskazałeś, że IQueryable jest wynikiem zapytania linq do encji, które nie jest poprawną instrukcją. MyDatabaseContext.Cars.Where(x => x.Name == "Test") zwraca obiekt IQueryable, który podczas iteracji wykonuje zapytanie w bazie danych. (Iteracja ma miejsce, gdy wykonujesz nad nią foreach). Więc nie zawiera jeszcze zestawu wyników, tylko zapytanie.
Dwukrotne wykonanie pętli nad samochodami generuje 2 identyczne zapytania do bazy danych i zwraca 2 identyczne zestawy wyników. Jeśli chcesz zachować dane. musisz wywołać ToArray lub ToList lub po manipulacji wykonaj zapisanie zmian przed ponownym wykonaniem iteracji.
Iteracja po IQueryable
pobiera zestaw wyników z bazy danych w trakcie, jak jestem pewien, że wiesz. To, co zaobserwowałem w tej i innych sytuacjach, to to, że ten wynik nie jest buforowany, więc często można zauważyć, że ponowne iterowanie po IQueryable
spowoduje ponowne uruchomienie zapytania, a zatem Twoje modyfikacje nie zostaną zachowane, ponieważ otrzymujesz nowy zestaw wyników, na który ten kod nigdy nie miał wpływu.
Powodem, dla którego to działa, gdy najpierw wywołujesz ToList()
i powtarzasz wynik, jest to, że ToList()
pobiera i materializuje cały zestaw wyników, który nie jest już powiązany z zawartością bazy danych i jest tak naprawdę tylko kopię tego, co zwróciła baza danych.
Jedynym sposobem, aby upewnić się, że zmiany zostaną zachowane, jest działanie na lokalnej kopii danych, tj. podniesienie jej z obszaru IQueryable
. Może to być tak proste, jak zapisanie IEnumerable
zestawu wyników (tj. wyniku ToEnumerable()
), który następnie zwróci ten sam zestaw wyników za każdym razem, gdy go wyliczasz, ale w przeciwieństwie do ToList()
nie spowoduje to natychmiastowej oceny.
Podobne pytania
Nowe pytania
c#
C # (wymawiane „patrz ostro”) jest językiem programowania wysokiego poziomu, statycznie typowanym, wieloparadygmatowym opracowanym przez firmę Microsoft. Kod C # zwykle jest przeznaczony dla rodziny narzędzi Microsoft .NET i czasów wykonywania, do których należą między innymi .NET Framework, .NET Core i Xamarin. Użyj tego tagu w przypadku pytań dotyczących kodu napisanego w C # lub C # formalnej specyfikacji.