我一直在获取ManyToMany关系。我有两个实体Offer
和OfferType
。我只在OfferEntity
上定义了ManyToMany关系,在数据库中用多个OfferType
保存优惠似乎很好——我看到了正确的联接表。
OfferEntity.php
/**
* Offer Entity
*
* @ORM'Table(name="offer")
* @ORM'Entity(repositoryClass="ProjectBundle'Repository'OfferRepository")
*/
class Offer
{
/**
* @Assert'Count(
* min = "1",
* minMessage = "You must specify at least one offer type."
* )
* @ORM'ManyToMany(targetEntity="OfferType")
*/
private $types;
public function __construct()
{
$this->types = new ArrayCollection();
}
/**
* @return ArrayCollection
*/
public function getTypes()
{
return $this->types;
}
(...)
现在,我想将所有types
分配给offer
。我这样试过:
// $offer is an Entity
$query = $em->createQueryBuilder()
->select('offer.types')
->from('ProjectBundle:Offer', 'offer')
->where('offer = :offer')
->setParameters([
'offer' => $offer
]);
不幸的是,我得到错误:
[2/2] QueryException: [Semantical Error] line 0, col 13 near 'types FROM ProjectBundle:Offer': Error: Invalid PathExpression. Must be a **StateFieldPathExpression**.
[1/2] QueryException: SELECT offer.types FROM ProjectBundle:Offer offer WHERE offer = :offer
基于StackOverflow对类似问题的回答,尝试使用IDENTITY()
:
// $offer is an Entity
$query = $em->createQueryBuilder()
->select('IDENTITY(offer.types)')
->from('ProjectBundle:Offer', 'offer')
->where('offer = :offer')
->setParameters([
'offer' => $offer
]);
但我有:
[2/2] QueryException: [Semantical Error] line 0, col 22 near 'types) FROM ProjectBundle:Offer': Error: Invalid PathExpression. Must be a SingleValuedAssociationField.
[1/2] QueryException: SELECT IDENTITY(offer.types) FROM ProjectBundle:Offer offer WHERE offer = :offer
我真的很感激任何关于建立ManyToMany关系的暗示,也许我的方法不正确?
您的方法不太正确。您需要加入要加载的实体。你应该多花点时间阅读关于实体关系的学说文档;querybuilder。
像这样。
$query = $em->createQueryBuilder()
->select('offer', 'types')
->from('ProjectBundle:Offer', 'offer')
->join('offer.types', 'types')
->where('offer = :offer')
->setParameters([
'offer' => $offer
]);
然后您的结果将包含您想要的内容。
注意:您甚至没有加入类型以从优惠中获得类型,您也可以使用
$offer->getTypes()
类型会以标准的教条方式懒惰加载。
但是按照上面的方式查询它会提前加载类型,这样可以避免延迟加载。这可能是一种更好的方法,也可能不是,具体取决于需求。
如果只在一侧设置多对多映射,则只能查询Offer
,然后从中检索类型:
$builder = $em->createQueryBuilder()
->select('o', 't')
->from('ProjectBundle:Offer', 'o')
->join('o.types', 't')
->where('o.id = :offer')
->setParameter('offer', $offerId);
$offer = $builder->getQuery()->getOneOrNullResult();
$types = $offer->getTypes();
这是假设您只有$offerId
可以使用。如果你已经有了完整的Offer
实例,你也可以直接调用它的getTypes()
,剩下的由条令来处理。
如果你要在OfferType
实体上定义逆映射,比如:
class OfferType
{
/**
* @ORM'ManyToMany(targetEntity="Offer", mappedBy="types")
*/
private $offers;
}
您可以只查询以下类型:
$builder = $em->createQueryBuilder()
->select('t')
->from('ProjectBundle:OfferType', 't')
->join('t.offers', 'o')
->where('o = :offer')
->setParameter('offer', $offer);
$types = $builder->getQuery()->getResult();