到目前为止,我已经尝试了以下方法,但是我一直只获得主要的Entity信息,而未将实体加入结果:
选项1(使用ResultSetMapping构建器):
$rsm = new ResultSetMappingBuilder(
$this->_em,
ResultSetMappingBuilder::COLUMN_RENAMING_INCREMENT
);
$rsm->addRootEntityFromClassMetadata(
'CountryApp\StoreBundle\Entity\Product', 'p'
);
$rsm->addJoinedEntityFromClassMetadata(
'CountryApp\StoreBundle\Entity\Category', 'c', 'p', 'category'
);
$rsm->addJoinedEntityFromClassMetadata(
'CountryApp\StoreBundle\Entity\CustomerProductPrice', 'cpp', 'p', 'customerPrices'
);
$result = $this->_em
->createNativeQuery(
'
SELECT
p.id,
p.code,
p.name,
p.cost,
p.rrp,
p.status,
p.notes,
p.out_of_stock_since,
p.available_in,
c.id,
c.name,
c.code,
cpp.id,
cpp.price
FROM product as p
JOIN category as c ON c.id = p.category_id AND p.status != "DELETED"
LEFT JOIN customer_product_price as cpp ON cpp.product_id = p.id AND cpp.customer_id = :customer
', $rsm
)
->setParameter('customer', $customerId)
->getResult(Query::HYDRATE_ARRAY)
;
选项2 :(使用QueryBuild和FetchMode)
$qb = $this->createQueryBuilder('p');
$result = $qb
->select('p')
->addSelect('c')
->addSelect('cpp')
->join(
'CountryApp\StoreBundle\Entity\Category',
'c',
Join::WITH,
$qb->expr()
->eq('c', 'p.category')
)
->leftJoin(
'CountryApp\StoreBundle\Entity\CustomerProductPrice',
'cpp',
Join::WITH,
$qb->expr()
->andX(
$qb->expr()
->eq('p', 'cpp.product'),
$qb->expr()
->eq('cpp.customer', ':customer')
)
)
->setParameter('customer', $customerId)
->getQuery()
->setFetchMode(
'CountryApp\StoreBundle\Entity\Category', 'product', ClassMetadata::FETCH_EAGER
)
->setFetchMode(
'CountryApp\StoreBundle\Entity\CustomerProductPrice', 'product', ClassMetadata::FETCH_EAGER
)
->getResult(Query::HYDRATE_ARRAY)
;
请告知您有关如何进行此工作的想法。我想获得以下结构:
[
0 => [
Product[
..
]
Category[
..
]
CustomerProductPrice[
..
]
],
1 => [
Product[
..
]
Category[
..
]
CustomerProductPrice[
..
]
],
..
.
]
答案 0 :(得分:0)
使用学说时,您可以在实体内部定义关系。
您可以在这里https://symfony.com/doc/current/doctrine/associations.html了解更多信息,请始终阅读文档和最佳实践。我不知道您是否正在使用Symfony,但这是一个很好的例子,比Doctrine文档更容易理解。
/**
* @ORM\Entity()
*/
class Product
{
// ...
/**
* @ORM\ManyToOne(targetEntity="App\Entity\Category", inversedBy="products")
*/
private $category;
public function getCategory(): ?Category
{
return $this->category;
}
public function setCategory(?Category $category): self
{
$this->category = $category;
return $this;
}
}
如您在此处看到的,您定义了一个包含所有关联和属性的实体。
通常,默认情况下,如果您调用$product->getCategory()
,则关联将被延迟加载,类别将被延迟加载。如果您不喜欢延迟加载,可以随时尝试使用
/**
* @ManyToOne(targetEntity="Category", cascade={"all"}, fetch="EAGER")
*/
您将收到一系列产品,其中每个产品都有一个名为category的属性,并且其中包含Category实体。
这是CakePHP之间的主要区别,因为在CakePHP中,您分别获得了所有关联,而在Symfony中,则得到了关联树。
您的查询似乎太复杂了,在大多数情况下,您根本不需要像这样修改查询。但是对于延迟加载要格外小心,如果您在庞大的列表上延迟加载数据,最终将导致性能下降。