Entity Framework, Lazy loading

0

Witam wszystkich!
Uczę się ostatnio o EF i napotykam na dwie wykluczające się opinie. Według jednej lazy loading powinno się prawie zawsze wyłączać aby uniknąć wysyłania masy zapytań do bazy danych, np. w takim wypadku:

//kontroler
public ActionResult Customers()
{
	var ctx = new NorthwindEntities();
	var qry = from c in ctx.Customers
		      select c;

	return(qry.toList());
}

// i w widoku teraz
@foreach(var m in Model)
{
	<div>@m.CompanyName: #/Orders - @m.Orders.Count()</div>
}

W innym kursie natomiast wyczytałem że praktycznie wszystko robi się teraz przy pomocy lazy loadingu...
Prosiłbym bardziej doświadczonych kolegów i koleżanki o wyjaśnienie mi jak to w końcu jest, w jakim przypadku używać lazy loadingu, w jakim eager loadingu i czy rzeczywiście lepiej prawie zawsze wyłączać lazy loading.

7

Wyłączać lazy loading chcą głównie ludzie, którzy nie rozumieją jak działają ORMy, po co się ich używa i forsują architekturę zwaną "encja na twarz i pchasz" (tudzież mniej metaforycznie "wysraj bazę na ekran").

W sytuacji, gdy klas reprezentujących rekordy bazy danych używa jako viewmodeli, to faktycznie lazy loading spowoduje problemy wydajnościowe. Ale ich przyczyną będzie architektura (czy raczej jej brak) oraz łamanie SRP, nie lazy loading sam w sobie. Ale jak się stosuje jakąś sensowną architekturę, w której obiekty GUI i obiekty ORMa, to różne typy, to tego problemu nie ma w ogóle. Jeśli viewmodel nie jest obiektem ORMa, to nie ma szans żeby ORM próbował nagle coś z bazy dociągać, więc na żadne zbędne selecty nie ma co liczyć. Po prostu dobra architektura rozwiązuje dylemat konfiguracji ORMa za nas.

Problem może zatem wystąpić w logice biznesowej, gdy operujemy na jakiejś encji i encjach zależnych od niej. Np. Invoice, Customer, Discount i kolekcja InvoiceItem. I teraz:

  1. Chcemy zmienić kontrahenta - oczywistym jest, że nie chcemy wczytywać wszystkich pozycji faktury w tym celu.
  2. Chcemy obliczyć rabat, w zależności od tego, ile lat kontrahent z nami współpracuje. Raczej nie ma sensu ładowanie obiektu Discount, jeśli warunek nie jest spełniony.
  3. Chcemy obliczyć kwotę faktury - oczywistym jest, że nie ma sensu doczytywanie ich po kolei, chcemy je wszystkie na raz.

Wniosek - ładujemy leniwie gdy:

  1. wiemy, że czegoś nie potrzebujemy;
  2. nie wiemy, czy czegoś potrzebujemy;
  3. będziemy czegoś potrzebowali lub nie w zależności od innych warunków.

Jedynie, gdy jesteśmy pewni, że czegoś potrzebujemy, to ładujmy to zachłannie.

1 użytkowników online, w tym zalogowanych: 0, gości: 1