У меня есть следующая проблема, и я не вижу никакого решения (даже менее вероятно после анализа исходного кода доктрины). Проблема заключается в следующем:Доктрина Многие из многих недостатков
У меня есть два класса сущности, скажем, Автор и Книга. Мое предположение состоит в том, что одна книга может быть написана многими авторами, так что это будет отношение «многие ко многим» к Автору в качестве владельца. Теперь я хочу иметь одно действие, в котором я могу создать новую книгу и сразу назначить ее существующему автору, и я знаю идентификатор автора, поэтому не требуется фактически выбирать автора из базы данных. И поэтому я могу попытаться:
$book = new Book();
//assign data to book
$author = $em->getPartialReference('Author', $idOfAuthor);
$author->addBook($book);
$em->persist($author);
$em->flush();
В чем проблема с вышеуказанным кодом? Предположим, что отношение имеет cascade = "persist". Если кто-то из вас попытается это сделать, вы получите действительно странный результат: книга будет добавлена в базу данных, но отношение не будет сохранено, потому что частичная ссылка отмечена как readOnly в доктрине 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();
Это один работает, но она будет выбирать все данные автора в строке, что я уже комментировал, как «проблематично», потому что прокси-класс при условии, доктрина в качестве ссылки будет lazy-load все атрибуты при любом вызове метода, выполняемом автором, с одним исключением и getId(), который, очевидно, бесполезен в этой ситуации.
Так что мой вопрос: Я не прав? Я что-то пропустил?
Да, вы правы, это именно то, что я имел в виду, и почти точно, что я вижу. Если быть точным - доктрина выполняет совершенно ненужный выбор в ответ на вызов addBook() (а не флеш), чтобы предоставлять данные в случае, если addBook() возвращает любые данные из объекта. Есть ли способ сделать это правильно, не выполняя выбор (конечно, я все еще хочу, чтобы автор был стороной, владеющей отношениями, я прекрасно понимаю, что это будет работать наоборот)? – Mikz
Единственный способ, которым я знаю, - перейти на низкоуровневый и использовать собственный SQL-запрос. Подробнее см. В [этот пост] (http://stackoverflow.com/questions/3325012/execute-raw-sql-using-doctrine-2). Еще одна вещь, которую следует учитывать: насколько важна производительность в этом случае? Стоит ли отойти от рамочных соглашений, чтобы сэкономить время на несколько миллисекунд? (Это не риторический, но что-то стоит подумать.) – Rob
Большое спасибо за ваши ответы. В этом случае производительность не так важна, потому что я создаю небольшую внутреннюю систему компании для управления данными. Он будет использоваться менее чем 20 людьми (отдел SEO и контент-провайдеры), и он не будет содержать много данных. Однако мне просто интересно, как все работает, и я всегда стараюсь делать все как можно эффективнее - пока это не потребует больше усилий, чем того стоит. В этом конкретном случае это не стоит :). – Mikz