2013-12-10 101 views
0

我有下面的問題,我看不到任何解決方案(分析教條源代碼後甚至不太可能)。問題如下:學說多到多瑕疵

我有兩個實體類,讓我們說作者和書。我的假設是,一本書可以由許多作者編寫,所以它將與作爲所有者的Author有多對多的關係。 現在我想要創建一個新書,並立即將其分配給現有作者,並且我知道作者的ID,因此不需要從數據庫中真正選擇作者。所以我可以嘗試:

$book = new Book(); 
//assign data to book 
$author = $em->getPartialReference('Author', $idOfAuthor); 
$author->addBook($book); 
$em->persist($author); 
$em->flush(); 

上述代碼有什麼問題?假設關係具有cascade =「persist」。如果你們中的任何一個人會這樣做,你會得到非常奇怪的結果:書會被添加到數據庫中,但是關係不會被保存,因爲部分引用被標記爲只讀在UnitOfWork教條中,並且因爲該教義不會保存對其進行的任何修改,但出於某種原因,它將遵循級聯持久性。

所以我們可以嘗試不同的方法:

$book = new Book(); 
//assign data to book 
$author = $em->getReference('Author', $idOfAuthor); 
$author->addBook($book); //here's problematic line 
$em->persist($author); 
$em->flush(); 

那一個作品,但它會選擇線的作者,我已經評價爲「有問題」的所有數據,因爲學說提供作爲參考的代理類將延遲加載在作者上執行的任何方法調用中的所有屬性,只有一個例外,它是getId(),在這種情況下顯然是無用的。

所以我的問題是: 我錯了嗎?我錯過了什麼?

回答

0

不,你沒有錯過任何東西。第二個樣本是正確的。 :)

我相信你看到的是當你刷新更新事務時,它仍然首先執行select語句來檢索相關記錄。從SQL的角度來看,這是效率低下的,但是這是Doctrine的工作方式。

+0

是的,你是對的,這正是我的意思,幾乎正是我所看到的。確切地說 - 爲了在addBook()返回實體的任何數據時提供數據,doctrine執行完全不必要的選擇來響應addBook()調用(不刷新)。有沒有辦法做到這一點,而沒有執行選擇(當然,我仍然希望作者是關係的擁有者,我完全知道它會以相反的方式工作)? – Mikz

+0

我知道的唯一方法是走低級,並使用本機SQL查詢。有關詳細信息,請參閱[本文](http://stackoverflow.com/questions/3325012/execute-raw-sql-using-doctrine-2)。還有一件需要考慮的事情:在這種情況下性能有多重要?值得離開框架約定來削減幾毫秒的執行時間嗎? (這不是修辭,而是值得思考的問題。) – Rob

+0

非常感謝您的回答。在這種情況下,績效並不那麼重要,因爲我正在創建一個小型的內部公司數據管理系統。它將被少於20人使用(SEO部門和內容提供商),它不會包含太多數據。然而,我只是對事物的工作方式感到好奇,而且我總是儘可能高效地做事 - 只要它不需要付出更多的努力。在這種情況下,這不值得:)。 – Mikz