Seriály Reklama
Vývojářské akce Spřízněné servery

Lazy, eager, explicit loading – o co jde?

Jiří Činčura | Vydáno 16. června 2008 | Komentářů: 8 | .NET

Často se střetávám s dotazy na různé typy načítání – především s nástupem používání LINQu pro získávání dat z SQL databází – a jejich ne vždy přesné pochopení. Pokusím se tedy v tomto krátkém článku vysvětlit, jak se jednotlivé typy liší a na co (ne)jsou vhodné. Jejich názvy nebudu překládat, neboť podle mého názoru je pro vývojáře vhodné si osvojit původní termíny.

reklama

Často se střetávám s dotazy na různé typy načítání – především s nástupem používání LINQu pro získávání dat z SQL databází – a jejich ne vždy přesné pochopení. Pokusím se tedy v tomto krátkém článku vysvětlit, jak se jednotlivé typy liší a na co (ne)jsou vhodné. Jejich názvy nebudu překládat, neboť podle mého názoru je pro vývojáře vhodné si osvojit původní termíny.

Lazy loading

Začněme s typem, který je běžný v LINQ to SQL – lazy loading. Při tomto přístupu jsou data získávána tak, jak programátor přistupuje k proměnným a prochází grafem. Jako příklad uveďme:

foreach(Order o in customer.Orders)
{ ... }

a předpokládáme, že tento kód je zanořen ve vnějším cyklu, který prochází kolekci „Customers“. Ve chvíli, kdy program vstupuje to tohoto vnitřního cyklu, je úložiště (nejčastěji tedy relační databáze) dotázáno na vrácení všech „objednávek příslušejících zákazníkovi“. Výhodou tohoto přístupu je jednoduchost pro programátora. Nemusí se starat o to, zdali má data načtena atp. Na druhou stranu nemusí být vždy jasné, v jaké části programu skutečně k načtení dojde. Tento přistup je vhodný pro několik málo dotazů do třeba číselníků. Jakmile iterujeme přes větší kolekci a dotahujeme další údaje, plýtváme zbytečně prostředky a časem, neboť se dotazy do databáze posílají jednotlivě.

Eager loading

Pro tento případ je mnohem vhodnější eager loading. Data zde načteme „do foroty“ ihned při spuštění prvního příkazu. Např. v Entity Frameworku můžeme využít metody „Include“, která nám zajistí vytvoření spojení (join) tabulek a získání všech dat přímo.

foreach(Customer customer in entities.Customers.Include(„Orders“))
{
  foreach(Order o in customer.Orders)
  { ... }
}

Díky tomu máme všechna data dostupná na klientovi a při procházení již není třeba dělat další dotazy do databáze. Není tedy těžké nahlédnout, že v případě procházení celé kolekce a přidružených objektů je tento přístup více než vhodný. Na druhou stranu je třeba velmi opatrně další tabulky přidávat, neboť je možné velmi jednoduše vytvořit „velký“ dotaz, který vrátí enormní množství dat a dojde k zahlcení linky nebo klienta.

 

Explicit loading

Lazy loading a eager loading šly tak trochu proti sobě. Naproti tomu explicit loading je pověstným cimrmanovským úkrokem stranou. Pokud se rozhodnete využívat tento postup řídíte si načítání dat sami, podobně jako u eager loading, nicméně získáváme pouze menší kousky dat podobně jako u lazy loading. Explicit loading je mj. standardní chování LINQ to Entities a Entity Frameworku. Jak to tedy funguje? Při procházení kolekce, v našem případě „Customers“, chceme-li dostat objednávky konkrétního (právě zpracovávaného) zákazníka, musíme před zpracováním této kolekce zavolat metodu „Load“.

foreach(Customer customer in entities.Customers)
{
  if (!customer.Orders.IsLoaded)
    customer.Orders.Load();
  foreach(Order o in customer.Orders)
  { ... }
}

Zbytek zpracování se pak neliší. Všimněte si též, že díky schopnosti Entity Frameworku cacheovat načtené objekty není třeba data získávat znova, byla-li již jednou načtena (property IsLoaded). Výhodou tohoto postupu je jasná viditelnost, kdy k načítání dat dochází (resp. kdy se o to kód pokusí). Nevýhodou je naopak, při procházení velkých kolekcí, nutnost poslat velký počet dotazů (zde je vhodnější použít eager loading).

 

Z tohoto krátkého přehledu je vidět, že ani jeden přístup není ten nejlepší a na každé úkony se může hodit něco jiného. Důležité je vždy dobře rozmyslet postup a samozřejmě rozhodnutí ověřit testováním, aby byly zohledněny všechny aspekty (které nemusely být při rozhodování známy).

V režimu TEXT nejsou povoleny žádné HTML značky. Odstavce jsou vytvořeny automaticky, webové adresy a e-maily jsou převedeny na odkazy. V režimu "HTML" jsou povoleny následující elementy: a b i cite strong em p br code blockquote ul ol li. Redakce si vyhrazuje právo komentáře mazat.








8 komentářů | řadit podle data

Hmm,

kalerab 16. června 2008 213.164.22.×××

Podla mna by MS mohol trosku 'pribrzdit' s novymi vlastnostami. Clovek este riadne neabsorboval generika a uz je to za vagon este komplikovanejsich veci. Ok, usetri to kopec riadkov kodu, ale citatelnost kodu sa akosi zacina stracat.

RE: Hmm,

Reakce na Hmm, vlko 16. června 2008 http://vlko.zilina.n… 78.99.42.×××

Najskor by som mal trosku postreh k clanku, pretoze fakt nevidim rozdiel medzi lazy loading a explicit loading, pretoze

if (!customer.Orders.IsLoaded)

customer.Orders.Load();

pri lazy loadingu sa zavola na pozadi pri pristupe k property Orders. Mozno ste tu tuto zmienku uviedli preto, lebo Entity Framework lazy loading nepodporuje.

Dalej pri linq ak definujeme join, tak ten sa nacitava pomocou eager loadingu. Cize Linq to sql vie aj eager aj lazy loading (ak samozrejme specifikacie nekecaju:)

Inak ale dobry clanok, to len ja som asi stoural:)

To kalerab:

microsoft nevymysla nove vlastnosti, ale toto je standardne chovanie vsetkych orm wraperov, takze keby to linq, alebo entity framework neobsahoval, urcite by v dnesnej dobe neprerazil

RE: Hmm,

Reakce na RE: Hmm, kalerab 17. června 2008 213.164.22.×××

Ak som to spravne pochopil, tak Linq funguje nad akoukolvek mnozinou dat (ako query) a EntityFramework je ten OR/M.

Tiez som mal na mysli "var" premenne, Extension metody ... vcelku bordel z toho zacina byt.

RE: Hmm,

Reakce na RE: Hmm, Jiří Činčura 18. června 2008 http://www.x2develop… 84.42.229.×××

LINQ je jen rozsireni jazyka. Umoznuje filtrovat, ziskavat apod. data z ruznych zdroju (predne tedy IQueryable a IEnumerable). Jedna z implementaci je LINQ to SQL, coz je (zjednodusene) moznost dotazovat se do MS SQL serveru na data.

Entity Framework take obsahuje podporu pro LINQ. Nicmene EF je kompletni OR mapper (konceptualni model <-> fyzicky model atd.).

LINQ to SQL podporuje jen MS SQL. Ostatni DB maji smulu (ano slo by to obejit, ale proc, kdyz "staci" napsat provider pro EF - kde jsou i vetsi moznosti, nez jen dotazovani). Je to tedy jaksi EF na diete.

A aby toho nebylo malo, LINQ to <cokoli> si muzete lehce napsat, viz treba http://blog.vyvojar.cz/jirka/archive/200….

LINQ to SQL (nebo i <cokoli>) neni nejakym protikladem k Entity Frameworku. Jsou to dve ruzne veci, ktere se trochu prolinaji.

RE: Hmm,

Reakce na RE: Hmm, Jiří Činčura 18. června 2008 84.42.229.×××

ad lazy vs. explicit> v tomto pripade to vypada stejne. Ale pokud mate slozitejsi volani metod, nemusi byt vzdy zrejme, kde se dany objekt bude tahat z DB. Kdezto, kdyz musim zavolat Load, vim presne, kdy se tak stalo.

ad linq2sql eager> ano, ale tim jsem rekl, ze tyto data chci, v ramci tohoto dotazu. Pri pouziti Include() je myslenka takova, ze si vezmu puvodni data a z nich pak pristoupim k dalsim v asociaci. Vysledek je stejny (pokud budou stejne dotazy), background za tim malinko odlisny.

RE: Hmm,

Reakce na RE: Hmm, vlko 18. června 2008 http://vlko.zilina.n… 91.127.9.×××

Ad lazy vs. explicit: neskor som si to uvedomil, ze je to tak myslene, ale uz bol komentar poslany:)

Trosku ma zmiatlo asi to, ze clanok je venovany hlavne Entity Frameworku, povodne som si myslel, ze ide o vseobecny uvod pre orm mapper techniky vseobecne.

Uff to sa uz zamotavam:)

RE: Hmm,

Reakce na RE: Hmm, Jiří Činčura 18. června 2008 http://www.x2develop… 84.42.229.×××

Clanek byl bran jako obecny uvod do xxx loading metod. Ale aby to bylo .NET vyvojare stravitelnejsi, zvolil jsem LINQ to SQL resp. Entity Framework jako ukazky. :)

Lazy evaluation

Jan Stoklasa 2. srpna 2008 http://www.linq.cz 88.100.241.×××

Dobrý den,

na svém blogu http://www.linq.cz jsem zrovna napsal o líném vyhodnocování (lazy loading, lazy evaluation) z trochu jiného pohledu, možná Vás to zaujme...

Uživatel

Pro zobrazení informací o svém účtu se musíte přihlásit. Pokud ještě nemáte svůj účet, tak si ho prosím vytvořte!

Reklama
Odběr článků

Pokud se přihlásíte k odběru zpráv, pošle Vám systém každý týden e-mail se seznamem posledních článků.

Zdrojak .NET Hosting Reklama
 
  Copyright 2002-2007 Devmasters s.r.o., Michal Bláha a autoři | running on Nemesis Publishing | Právní doložka  
TOPlist