Doctrine dotaz na všechny usery a jejich company zavolá sql pro každou company

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
SvvimX
Člen | 65
+
0
-

Ahoj,

doctrine mi dělá nepříjemnou věc, když jednoduše vytáhnu všechny entity user a iteruju nad nimy a v každé vypíšu:

$user -> company -> title;

Zavolá si Doctrine pro každou jednu comapny vlastní sql. Je nějak jednoduše možné donutit Doctrine, aby rovnou v jednom dotazu s JOIN nebo ve dvouch a následně spojením přes PHP nebo mě je jedno jak vytáhl všechno? Nejlépe tak, aby poznal, že šahám na jeho proxy objekty ale aby je vytáhl z DB všechny naráz a ne po jednom.

Nebo je jediná možnost v repository dopsat metodu getAllWithComapnies, kde si napíšu ono spojení?

Přijde mi to zvláštní, nemůžu být první, kdo todle řeší a přesto sem nic o tom nenašel..

Díky

enumag
Člen | 2118
+
0
-

Je to známý bug a snad bude konečně opraven v příští verzi Doctrine. Zatím se to myslím obchází přes DQL. Odkaz na ten bug nemám uložený, Filip Procházka ti k tomu asi řekne víc.

mkoubik
Člen | 728
+
0
-

Není to (pokud vím) ani tak bug jako spíš feature, říká se tomu N + 1 problem. Nejlepší™ je si všechny entity které budeš potřebovat najoinovat v DQL. Navíc považuju za zlo předávat entity přímo do šablony, je to objekt z persistentní vrstvy a jako takový (podobně jako ActiveRow z NDB) tam nemá co dělat. Já si většinou ty entity překopírovávám do nějakého DTO, které definuje kontrakt mezi presenterem a šablonou. Chápu že se lidem moc nechce se s tím psát, ale v případech jako je tenhle to oceníš (nestane se ti že by ti kodér ovlivnil zátěž db).

Filip Procházka
Moderator | 4668
+
0
-

Pracovat s entitami takto je dobré maximálně na prototypování. DQLkům se nikdy v důsledku nevyhneš. Řešením je hodit company do joinu :)

Doctrina ovšem bude umět brzy velice efektivní způsob sahání na data, pomocí dočasné změny fetch mode už teď to u jednoho typu relace umí, dodělávají další :)

SvvimX
Člen | 65
+
0
-

ok, takže správně se to dělá tak, že si podědím repositories do vlastních tříd (říkám jim DAO) a napíšu si vlastní metody typu GetByWithCompanies?

Nebo jak využíváte Doctrine v Nette vy? Já mám entity, nad tím DAO třídy nad tím Managery (=services) a s těmi komunikuji presentery.

Jiří Nápravník
Člen | 710
+
0
-

SvvimX napsal(a):
Nebo jak využíváte Doctrine v Nette vy? Já mám entity, nad tím DAO třídy nad tím Managery (=services) a s těmi komunikuji presentery.

Využíváme Kdyby/Doctrine – které vytváří automaticky DAO pro jednotlivé Entity. To konkrétní DAO si přidám do facade – tj v podstatě tvoje Manager – tam mám pak jednotlivé metody volající ono DAO, případně vytvářející dotaz přes DQL