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.
Implementacja 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.

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.

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.

Świetne wyjaśnienie różnic pomiędzy tymi dwoma sposobami ładowania. Są to wszystkie różnice, czy o jakichś jeszcze nie wspomniałeś?
I wrote an article with programming views on Lazy Loading vs Eager Loading,
http://www.codedjava.com/2017/09/eager-loading-vs-lazy-loading.html
Thanks.