Chciałbym aby ktoś mi swoimi słowami wytłumaczył czym jest LAZY LOADING i kiedy jest on dobry, a kiedy zły? (ja akurat pisze w asp.netmvc). Przeczytałem już trochę informacji na ten temat i jako takie wyrobiłem sobie o tym zdanie i wiedze, ale lubie jak ktoś tłumaczy pewne zagadnienie po swojemu żebym miał jakiś punkt odniesienia.
Reasumując chciałbym uzyskać odpowiedź na te pytania (swoimi słowami, przykładem, a nie w stylu “poszukaj w google”)
Piszesz zapytanie do danych w jednym miejscu, a zostanie ono wykonane dopiero w momencie kiedy będziesz tych danych potrzebował.
var dane = (from d in db.DaneSet .. select ... ); // tu się nie wykonuje
// dużo kodu ..
foreach(var dana in dane) // dopiero tu się faktycznie odwołujez i tu się wykona
{
}
Gdybyś od razu na zapytania wział coś co wymaga zmaterializowania, np.:
var dane = (from d in db.DaneSet .. select ... ).ToList();
… to by się od razu wykonało.
Koncepcja jest uniwersalna. Nie jest związana bezpośrednio z ASP.NET MVC. Generalnie chodzi o to, żeby ładować dane najpóźniej jak się da. Zaleta jest taka, że nie ładujemy danych niepotrzebnie, kiedy np. w wyniku jakiegoś if’a okaże się że ich nie używamy. Wadą, że zachowanie programu może być nieco bardziej niedeterministyczne. Trudniej też taki program się np. debuguje, bo załadowanie danych może nastąpić w zupełnie innym miejscu niż zapytanie.
Przez zapytanie program Ci przeskoczy, a nagle będzie wisieć w zupełnie dziwnym miejscu bo przechodząc przez kilka powiązań coś nie zostało załadowane. Łatwiej nad tym zapanować jeśli ładuje się od razu tam gdzie masz zapytanie.
Miałbyś IEnumerable anonimowej klasy z informacją “collection cannot be enumerated”.
Łatwo to sprawdzić. Nie wymaga bazy danych, np:
using System;
using System.Linq;
namespace ConsoleApplication4
{
class Person
{
public string Name { get; set; }
}
class Program
{
static void Main(string[] args)
{
Person[] people = {
new Person() { Name = "P1" },
new Person() { Name = "P2" },
new Person() { Name = "P3" }
};
var queryPeople = (from p in people
where p.Name.StartsWith("P")
select p); // nie ma danych
// lub people.Where(p = p.Name.StartsWith("P"))
var queryPeopleAsList = (from p in people
where p.Name.StartsWith("P")
select p).ToList(); // TU JUŻ BĘDĄ DANE
int x = 123, y = 1;
while (y x) { y++; }
foreach(Person p in people)
{
Console.WriteLine(p.Name);
}
}
}
}