我在我的 Symfony 5 專案中有 2 個物體:客戶端和模板。每個Client有一個或多個模板(OneToMany),每個模板只與一個Client(ManyToOne)相關。我有一個getTemplates()函式Client.php回傳的模板的集合。
我遇到的問題是,當我呼叫getTemplates()函式時,我從以下位置運行它:
$client = $entityManager->getRepository(Client::class)->find($id);
$templates = $client->getTemplates();
我得到了一個初始化 = false 的集合。
據我了解,為了避免不必要的請求,Symfony 創建了一個模板代理物件,它是null。為了使這項作業,我可以添加fetch="EAGER"
@ORM\OneToMany(targetEntity=Template::class, mappedBy="Client", orphanRemoval=true, fetch="EAGER")
添加它基本上使請求成為“真正的”模板物件(更多資訊在這里)。
我想要做的是讓我的 getTemplates 作業,而不必在我檢索所有客戶端時請求所有模板(有時我只需要顯示所有客戶端,然后從某個客戶端請求模板):
$templateRepository->findAll()
我知道如何解決我的問題,我只是想擁有最好的方式,而具有做請求的最小量到我的資料庫(基本上只呼叫它,當我需要它)。
總而言之,我想:
- findAll()我的客戶,而不檢索與客戶關聯的模板
- findAll()我的模板并獲取相關的客戶端 -當我添加 fetch="EAGER" 時,這當前有效,因為我獲得了對應于正確客戶端的“所有者”
uj5u.com熱心網友回復:
正如Yassinefikri解釋的那樣,Symfony 的默認行為是不請求鏈接的物體以避免性能不佳。
為了解決這個問題,您需要在存盤庫中使用適當的函式,您將在其中獲取客戶端并將它們與它們的模板連接起來。
這允許在沒有模板的情況下獲取所有客戶端,但也可以使用模板獲取所有客戶端,無論您是否需要它。
通過添加 afetch="EAGER"來更改 Symfony 的默認行為不是一個好習慣,您應該始終為所需結果創建一個函式,而不是更改默認行為(這會降低性能,特別是在處理大型資料庫時)。
- 編輯,更好(更優化)的解決問題的方法
正如Will B所說,這種行為來自 Doctrine ORM 而不是 Symfony (Symfony 經常與 Doctrine ORM 一起使用,但這通常適用于 ORM)。
實作預期結果的另一種(更好)方法是初始化物件(它將獲取鏈接的物體,而無需實際向資料庫發出JOIN請求 - initializeObject())。
總結
fetch="EAGER"如果可以,請不要使用,因為這確實是處理鏈接物體的作業方式,最好使用Will B或Yassinefikri 的解決方案來解決問題。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/343628.html
