Ответ 1
Текущая версия доктрины не поддерживает это.
запрос функции об этом в трееере проверки doctrine2.
Поэтому я надеюсь, что это будет реализовано в ближайшее время.
Я загружаю список многих объектов.
Эти объекты имеют связь "один ко многим" с другими объектами.
Я хочу загрузить все эти другие объекты в одном SQL-запросе (вместо одного запроса для каждого объекта в первом списке).
Как описано в документации doctrine2: http://www.doctrine-project.org/docs/orm/2.1/en/reference/dql-doctrine-query-language.html#temporarily-change-fetch-mode-in-dql это должно быть возможно при загрузке EAGER.
но он не работает, как описано.
мой код:
class User{
/**
* @ORM\OneToMany(targetEntity="Address", mappedBy="user", indexBy="id", fetch="EAGER")
*/
protected $addresses;
public function __construct(){
$this->addresses = new ArrayCollection();
}
}
class Address{
/**
* @ORM\ManyToOne(targetEntity="User", inversedBy="addresses")
* @ORM\JoinColumns({
* @ORM\JoinColumn(name="UserId", referencedColumnName="id")
* })
*/
private $user;
}
class UserRepository{
public function findUsersWithAddresses(){
return $this->getEntityManager()
->createQuery('SELECT u FROM MyBundle:User u ORDER BY u.name ASC')
->setFetchMode('MyBundle\Entity\User', 'addresses', \Doctrine\ORM\Mapping\ClassMetadata::FETCH_EAGER)
->setMaxResults(10)
->getResult();
}
}
Метод UserRepository:: findUsersWithAddresses() выполняет 11 SQL-запросов.
Как я могу сообщить Doctrine использовать только один SQL-запрос для загрузки адресов?
Я использую:
Текущая версия доктрины не поддерживает это.
запрос функции об этом в трееере проверки doctrine2.
Поэтому я надеюсь, что это будет реализовано в ближайшее время.
Согласно вашей ссылке:
Вы можете пометить ассоциацию много-к-одному или один-к-одному как выбранную временно для пакетной выборки этих объектов с использованием запроса WHERE.. IN
Похоже, что текущая версия Doctrine, к сожалению, не поддерживает загрузку в коллекцию "один ко многим".
Эта страница, похоже, подтверждает это предположение:
@OneToMany
Обязательные атрибуты:
targetEntity: FQCN ссылочного целевого объекта. Может быть неквалифицированное имя класса, если оба класса находятся в одном пространстве имен. ВАЖНО: Никакой ведущей обратной косой черты!
Дополнительные атрибуты:
- каскад: опция Cascade
- orphanRemoval: Boolean, который указывает, если сироты, обратные объекты OneToOne, которые не связаны ни с одним обладающий экземпляром, должен быть удален Doctrine. По умолчанию false.
- mappedBy: этот параметр указывает имя свойства в targetEntity это и есть собственная сторона этого отношения. Его обязательный атрибут для обратная сторона отношения.
Аннотация @OneToMany
не содержит атрибута fetch
, а не @OneToOne
и @ManyToOne
.
Забастовкa >
Я только заметил, что вы действительно можете получить связанные объекты, используя явный LEFT JOIN
в DQL:
SELECT u, a FROM User u
LEFT JOIN u.addresses a
Используйте LEFT JOIN
, а не внутренний JOIN
, или объекты с пустой коллекцией (User
без каких-либо Address
) будут опущены из набора результатов.
Как указано GusDeCool и webDEVILopers в комментариях, атрибут fetch
теперь поддерживается в @OneToMany
. Вышеприведенный ответ устарел.
У меня были точно такие же проблемы и обновился мой модуль доктрины в Zend Framework 2 до версии 2.5, и теперь все работает нормально. Вы можете проверить мой вопрос здесь