При использовании доктрины я заметил, что для удаления объекта мне нужно получить этот объект по заданному параметру (имя, идентификатор и т. Д.), А затем вызвать метод удаления. С другой стороны, в запросе я могу просто выполнить запрос на удаление.
Таким образом, похоже, использование стиля ORM требует двух операций, а общая операция sql требует одной операции. Вот почему, я немного запутываюсь, следует ли нам использовать операцию удаления (или обновления) в ORM? Разве это не хуже в производительности? Или есть что-то еще, что мне не хватает? Можно ли это сделать любым способом в стиле ORM?
В Doctrine2 вы можете вызвать delete на прокси-объекте, который не загружен из базы данных. Просто создайте «фиктивный» объект, что-то вроде:
$user = $em->getPartialReference('model\User', array('id' => $id)); $em->remove($user);
Он не требует первоначального запроса, но я не совсем уверен, что Doctrine все еще делает это внутренне на fush . Я не вижу его в SqlLog.
Просто чтобы добавить, я думаю, что это ожидаемое поведение любого приличного ORM. Он касается объектов и отношений. Он должен знать, что перед удалением чего-то существует. ORM – это не просто генератор запросов . Как правило, собственный запрос всегда будет быстрее в любом ORM. Любая ORM добавляет слой абстракции, и для ее выполнения требуется некоторое время. Это типичный компромисс, вы получаете некоторые причудливые функции и чистый код, но немного теряете производительность.
РЕДАКТИРОВАТЬ:
Я рад, что это сработало для вас. Фактически я наткнулся на другую проблему, которая заставила меня понять, что прокси и частичные объекты на самом деле не то же самое. Частичные объекты представляют экземпляр реального класса модели и заполняют его необходимыми значениями. После инициализации частичного объекта lazy-load больше не работает на нем. Например, если вы делаете частичный объект только с идентификатором и хотите удалить только в том случае, если другое поле объекта удовлетворяет некоторому условию, оно не будет работать, потому что это другое поле всегда будет нулевым.
С другой стороны, прокси-серверы работают с ленивой загрузкой и не разделяют проблем, которые имеют частичные объекты. Поэтому я настоятельно рекомендую не использовать метод getPartialReference
, вместо этого вы можете сделать что-то вроде:
$user = $em->getReference('model\User', $id); $em->remove($user);
Метод getReference
возвращает объект, если он уже загружен, или прокси-сервер, если это не так. Прокси-сервер может ленить все остальные значения, если / когда они вам понадобятся. Что касается вашего примера, они будут вести себя точно так же, но прокси-серверы, безусловно, лучший способ пойти.
Готово! для меня это сработало, как эта строка добавления 3:
$user = $em->getReference('model\User', $id); $em->remove($user); $em->flush();