Lazy Loading w asp.net mvc - co to jest?


(Shiva) #1

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.net mvc). 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")

1. Czym jest lazy loading?

this.Configuration.LazyLoadingEnabled = false;

.


(kowgli) #2

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.


(Shiva) #3

Czy gdybym zdebugował to

var dane = (from d in db.DaneSet .. select ... ); // tu się nie wykonuje

i postawił brakepointa po zmiennej “dane” to mialbym nulla w tej zmiennej “dane”?


(kowgli) #4

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);
            }
        }
    }
}