Lazy loading vs eager loading – Entity Framework

Entity Framework jest jedną z platform ORM, która pozwala na współpracę pomiędzy bazą danych a obiektowym językiem programowania. Dane które są pobierane za pośrednictwem EF są podzielone na dwa tryby: lazy loading lub eager loading.

Lazy loading (leniwe ładowanie) polega na każdorazowym odpytywaniu bazę danych o interesujące nas informacje (jeśli property nawigacyjne jest NULL). Jest domyślnym trybem w Entity.

Aby bardziej przybliżyć pojęcie “leniwego ładowania” najlepiej będzie jeżeli zobrazujemy go na przykładzie.
Baza danych składa się z dwóch tabel. Jedna zawiera informacje o nazwie drużyny piłkarskiej
natomiast druga o zawodnikach przypisanych do w/w zespołu. Zauważmy, że jest to relacja jeden do wielu tj. jeden zawodnik może być przypisany tylko do jednej drużyny lecz jedna drużyna może mieć wielu zawodników.
EF1Implementacja pobierania danych jest dość prosta. W pierwszej kolejności pobieramy tabele z zawodnikami a następnie pętlą wyświetlamy informacje na temat imienia, nazwiska piłkarza oraz drużyny w której gra. Trzecia linijka w kodzie służy do wyświetlania loga który jest połączony z naszą bazą danych.

using (testEntities test = new testEntities())
{
    test.Database.Log = Console.WriteLine;
    var lazyLoading = test.zawodnicies;
    foreach (var item in lazyLoading)
    {
        Console.WriteLine(item.Imie + " " + item.Nazwisko + " gra dla "
        + item.druzyny.NazwaDruzyny + " z ligi " + item.druzyny.Liga);
    }
    Console.ReadLine();
}

Po uruchomieniu programu widzimy, że nasze “leniwe ładowanie” wygenerowało trzy zapytania do naszej bazy danych. Przy tak małej ilości powiązań i rekordów jest to praktycznie niezauważalne ale przy większej ilości danych powstaje problem N+1.

EF_LL_console.jpeg

 

 


Eager loading (chciwe ładowanie) ogranicza zapytania do bazy kosztem pobrania i przechowywania wszystkich danych z konkretnych tabel w pamięci. Najlepiej będzie, jeśli zobrazujemy to na przykładzie z zawodnikami i drużynami.

Istotną rzeczą jest użycie słowa kluczowego “Include” które mówi Entity że teraz chcemy używać eager loading. Kod jest analogiczny w porówaniu z lazy loading poza 4 linijką kodu gdzie pobieramy wszystkie dane z tabeli: zawodnicy i drużyny.

using (testEntities test = new testEntities())
{
    test.Database.Log = Console.WriteLine;
    var eagerloading = test.zawodnicies.Include(x => x.druzyny);
    foreach (var item in eagerloading)
    {
        Console.WriteLine(item.Imie + " " + item.Nazwisko + " gra dla "
        + item.druzyny.NazwaDruzyny + " z ligi " + item.druzyny.Liga);
    }
    Console.ReadLine();
}

Możemy również w ramach IQueryable zrobić “selecta” – wtedy nie musimy dodawać “Include” ponieważ materializujemy zapytanie do postaci “listy”.

var result = context.Zawodnicy.Select(z => new
{
    Imie = z.Imie,
    Nazwisko = z.Nazwisko,
    NazwaDruzyny = z.druzyny.NazwaDruzyny
}).ToList();

Po uruchomieniu programu widzimy, że wygenerowaliśmy tylko jedno zapytanie do bazy, a otrzymaliśmy te same informacje jak w trybie lazy loading.

EF_GL.jpeg


Podsumowanie:
Kiedy używać Lazy loading a kiedy Eager loading.
Lepszym zastosowaniem dla użycia lazy loading jest wariant, gdy chcemy pozyskać jakieś pojedyncze informacje z jednej tabeli (np.gdy potrzebujemy tylko imiona i nazwiska piłkarzy a nie potrzebujemy pobierać informacji o drużynach i zaśmiecać sobie nimi pamięci).
Gdy potrzebujemy wszystkie informacje z relacyjnych tabel (np. drużyn i zawodników) wtedy najlepszym i najszybszym sposobem pozyskania danych będzie zastosowanie eager loading.

2 Comments on “Lazy loading vs eager loading – Entity Framework”

Leave a Reply

Your email address will not be published. Required fields are marked *