Symfony:如何在 OneToMany 关系(3 个实体)中对 ArrayCollection 进行排序?
Symfony : How to sort ArrayCollection in a OneToMany relation (3 entities)?
我有一款产品可以有一个或多个标签。
出于特殊原因,我有 3 个实体对应于:
Product
Tag
ProductTag
(关系):
我想按我的 ArrayCollection 标签类型排序。 此集合包含 ProductTag
个实体。
问题是我在ProductType
里没有type
属性,这个属性在Tag
实体里
产品
/**
* @ORM\OneToMany(targetEntity="ProductTag", mappedBy="product", cascade={"persist", "remove"})
* @Assert\Valid
*/
private $tags;
标签
/**
* @ORM\Column(type="string", length=15)
*/
private $type;
产品标签
/**
* @ORM\Column(name="Product_id", type="integer")
* @ORM\Id
*/
private $product_id;
/**
* @ORM\Column(name="Tag_id", type="integer")
* @ORM\Id
*/
private $tag_id;
/**
* @ORM\ManyToOne(targetEntity="Product", inversedBy="tags")
* @ORM\JoinColumn(name="Product_id", referencedColumnName="Product_id")
*/
private $product;
/**
* @ORM\ManyToOne(targetEntity="Tag")
* @ORM\JoinColumn(name="Tag_id", referencedColumnName="Tag_id")
*/
private $tag;
下面的解决方案不起作用 因为 ProductTag
没有 type
属性 :
// Product entity
/**
* @ORM\OneToMany(targetEntity="ProductTag", mappedBy="product", cascade={"persist", "remove"})
* @ORM\OrderBy({"type" = "ASC"})
* @Assert\Valid
*/
private $tags;
我想做这样的事情@ORM\OrderBy({"tag.type" = "ASC"})
。
有什么想法吗?
谢谢。
--- 编辑 ---
在 PhpMyAdmin 中,我创建了一个视图,用于获取标签数据和每个标签的产品 ID。
然后,在 Symfony 中,我创建了一个与我的视图相对应的实体。
在此实体的存储库中,我创建了一个按类型连接我的标签的查询。
public function findByProductGroupByType($productId)
{
return $this->getEntityManager()
->createQuery(
'SELECT v.tagTypeCode, v.tagType,
GROUP_CONCAT(v.tagCode) as tagCode,
GROUP_CONCAT(v.tagName) as tagName,
GROUP_CONCAT(v.picto) as tagPicto
FROM AppBundle:ProductTagView v
WHERE v.productId = :id
GROUP BY v.tagTypeCode
ORDER BY v.tagType ASC'
)->setParameter('id', $productId)
->getResult();
}
为了让它工作,有必要安装 this bundle 以便 Symfony 识别 GROUP_CONCAT
。安装后,在config.yml
中添加:
doctrine:
orm:
dql:
string_functions:
group_concat: DoctrineExtensions\Query\Mysql\GroupConcat
完整列表在这里:https://github.com/beberlei/DoctrineExtensions/blob/master/config/mysql.yml
查询 returns 是这样的:
array (size=2)
0 =>
array (size=5)
'tagTypeCode' => string 'KFEAT' (length=5)
'tagType' => string 'Key Feature' (length=11)
'tagCode' => string 'double_sanglage' (length=15)
'tagName' => string 'double sanglage' (length=15)
'tagPicto' => string 'double_sanglage.jpg' (length=19)
1 =>
array (size=5)
'tagTypeCode' => string 'SIZE' (length=4)
'tagType' => string 'Size' (length=4)
'tagCode' => string 'h26_ceintures,h21_ceintures' (length=27)
'tagName => string 'ceintures h26cm,ceintures H21 cm' (length=32)
'tagPicto' => string 'h26_ceintures.jpg,h21_ceintures.jpg' (length=35)
SIZE
类型的标签与 ,
分隔符连接。
你不能直接这样做。但是有一个解决方法。
向您添加订购标签 属性 产品实体:
private $orderedTags;
public function __construct()
{
//...
$this->orderedTags = new \Doctrine\Common\Collections\ArrayCollection();
}
创建一个新的学说事件监听器并在services.yml
中注册
services:
my.listener:
class: AppBundle\EventListener\OrderedTagsListener
arguments: ["@doctrine.orm.entity_manager"]
tags:
- { name: doctrine.event_listener, event: postLoad }
// src/AppBundle/EventListener/OrderedTagsListener.php
namespace AppBundle\EventListener;
use Doctrine\ORM\Event\LifecycleEventArgs;
use AppBundle\Entity\Product;
class OrderedTagsListener
{
private $em;
public function __construct($em)
{
$this->em = $em;
}
public function postPersist(LifecycleEventArgs $args)
{
$product = $args->getEntity();
// Retrieve your tags ordered with a query defined in your tags repository
$orderedTags = $this->em->getManager()->getRepository('AppBundle:Tags')->getOrderedTags($product);
$product->setOrderedTags();
}
}
我有一款产品可以有一个或多个标签。
出于特殊原因,我有 3 个实体对应于:
Product
Tag
ProductTag
(关系):
我想按我的 ArrayCollection 标签类型排序。 此集合包含 ProductTag
个实体。
问题是我在ProductType
里没有type
属性,这个属性在Tag
实体里
产品
/**
* @ORM\OneToMany(targetEntity="ProductTag", mappedBy="product", cascade={"persist", "remove"})
* @Assert\Valid
*/
private $tags;
标签
/**
* @ORM\Column(type="string", length=15)
*/
private $type;
产品标签
/**
* @ORM\Column(name="Product_id", type="integer")
* @ORM\Id
*/
private $product_id;
/**
* @ORM\Column(name="Tag_id", type="integer")
* @ORM\Id
*/
private $tag_id;
/**
* @ORM\ManyToOne(targetEntity="Product", inversedBy="tags")
* @ORM\JoinColumn(name="Product_id", referencedColumnName="Product_id")
*/
private $product;
/**
* @ORM\ManyToOne(targetEntity="Tag")
* @ORM\JoinColumn(name="Tag_id", referencedColumnName="Tag_id")
*/
private $tag;
下面的解决方案不起作用 因为 ProductTag
没有 type
属性 :
// Product entity
/**
* @ORM\OneToMany(targetEntity="ProductTag", mappedBy="product", cascade={"persist", "remove"})
* @ORM\OrderBy({"type" = "ASC"})
* @Assert\Valid
*/
private $tags;
我想做这样的事情@ORM\OrderBy({"tag.type" = "ASC"})
。
有什么想法吗?
谢谢。
--- 编辑 ---
在 PhpMyAdmin 中,我创建了一个视图,用于获取标签数据和每个标签的产品 ID。
然后,在 Symfony 中,我创建了一个与我的视图相对应的实体。 在此实体的存储库中,我创建了一个按类型连接我的标签的查询。
public function findByProductGroupByType($productId)
{
return $this->getEntityManager()
->createQuery(
'SELECT v.tagTypeCode, v.tagType,
GROUP_CONCAT(v.tagCode) as tagCode,
GROUP_CONCAT(v.tagName) as tagName,
GROUP_CONCAT(v.picto) as tagPicto
FROM AppBundle:ProductTagView v
WHERE v.productId = :id
GROUP BY v.tagTypeCode
ORDER BY v.tagType ASC'
)->setParameter('id', $productId)
->getResult();
}
为了让它工作,有必要安装 this bundle 以便 Symfony 识别 GROUP_CONCAT
。安装后,在config.yml
中添加:
doctrine:
orm:
dql:
string_functions:
group_concat: DoctrineExtensions\Query\Mysql\GroupConcat
完整列表在这里:https://github.com/beberlei/DoctrineExtensions/blob/master/config/mysql.yml
查询 returns 是这样的:
array (size=2)
0 =>
array (size=5)
'tagTypeCode' => string 'KFEAT' (length=5)
'tagType' => string 'Key Feature' (length=11)
'tagCode' => string 'double_sanglage' (length=15)
'tagName' => string 'double sanglage' (length=15)
'tagPicto' => string 'double_sanglage.jpg' (length=19)
1 =>
array (size=5)
'tagTypeCode' => string 'SIZE' (length=4)
'tagType' => string 'Size' (length=4)
'tagCode' => string 'h26_ceintures,h21_ceintures' (length=27)
'tagName => string 'ceintures h26cm,ceintures H21 cm' (length=32)
'tagPicto' => string 'h26_ceintures.jpg,h21_ceintures.jpg' (length=35)
SIZE
类型的标签与 ,
分隔符连接。
你不能直接这样做。但是有一个解决方法。
向您添加订购标签 属性 产品实体:
private $orderedTags; public function __construct() { //... $this->orderedTags = new \Doctrine\Common\Collections\ArrayCollection(); }
创建一个新的学说事件监听器并在services.yml
中注册services: my.listener: class: AppBundle\EventListener\OrderedTagsListener arguments: ["@doctrine.orm.entity_manager"] tags: - { name: doctrine.event_listener, event: postLoad } // src/AppBundle/EventListener/OrderedTagsListener.php namespace AppBundle\EventListener; use Doctrine\ORM\Event\LifecycleEventArgs; use AppBundle\Entity\Product; class OrderedTagsListener { private $em; public function __construct($em) { $this->em = $em; } public function postPersist(LifecycleEventArgs $args) { $product = $args->getEntity(); // Retrieve your tags ordered with a query defined in your tags repository $orderedTags = $this->em->getManager()->getRepository('AppBundle:Tags')->getOrderedTags($product); $product->setOrderedTags(); } }