Doctrine,如何连接具有多对多关系的表
Doctrine, how to join tables with many to many relation
我正在使用 Symfony 2、Doctrine 和 Query Builder。
我有 2 tables:产品和类别。
产品 ORM 文件包含以下内容:
manyToMany:
categories:
targetEntity: Pim\Component\Catalog\Model\CategoryInterface
joinTable:
name: pim_catalog_category_product
joinColumns:
product_id:
referencedColumnName: id
onDelete: CASCADE
inverseJoinColumns:
category_id:
referencedColumnName: id
onDelete: CASCADE
这样做的效果是,我有一个名为 "pim_catalog_category_product" 的 table 链接类别和产品。
我的类别 ORM 文件中没有关于产品的信息。
我正在尝试使用 QueryBuilder 构建查询,但我不明白如何从类别 table 的查询开始,该类别链接产品以便在产品上添加一些过滤器。
$qb = $this->getEntityManager()
->createQueryBuilder()
->addSelect('category')
->from($this->_entityName, 'category')
->join('Pim\Component\Catalog\Model\Product', 'product', 'WITH', 'category.id IN (product.categories);
但现在我收到以下错误:
Expected Literal, got 'product' at ... SELECT category FROM Pim\Bundle\CatalogBundle\Entity\Category category INNER JOIN Pim\Component\Catalog\Model\Product product WITH category.id IN (product.categories) at ...
有人可以帮助我吗?谢谢。
当你使用 ManyToMany 学说时,在后台为你做了很多关于关系管理的事情 'magic',这样你就可以进行快速连接,而无需考虑连接的笛卡尔积
$this->getEntityManager()
->createQueryBuilder()
->addSelect('product')
->from($this->_entityName, 'p')
->join('p.category')
或像
这样的快速冲洗
$product->setCategories($categories);
$em->persist($product);
$em->flush();
缺点是,为了让 doctrine 能够做到这一点 'magic' 您无权访问内部联接 table 您需要执行所需的联接.
此外,如果您不在 'category' 上定义反向关系,我认为学说无法为您管理此连接。但请注意,如果您有很多产品,这样做会产生很大的内存开销,因为 doctrine 会延迟加载您类别中的所有产品。
如果您不想定义反向关系(由于上述问题),解决方法是在您的关系 table 上定义一个实体(类似于 ProductCategory),然后定义2 此实体的 2 列上的 1->1 关系。然后,只要您想创建从类别开始并加入产品的查询构建器,就可以使用此实体作为桥梁,而无需在类别
上定义 M<->M 关系
类似于
$qb = $this->getEntityManager()
->createQueryBuilder()
->addSelect('c')
->from($this->_entityName, 'c')
->join('Pim\Component\Catalog\Model\ProductCategory', 'pc', 'WITH', 'c.id = pc.category_id')
->join('Pim\Component\Catalog\Model\Product', 'p', 'WITH', 'p.id = pc.product_id')
PS:尝试像上面的例子一样使用短别名,以避免更多的 "literal" 异常。
希望对您有所帮助,
亚历山德鲁·科索伊
我终于设法通过子查询和从 ManyToMany 关系加入 table 的正确方法解决了我的问题。
$qb2 = $this->getEntityManager()
->createQueryBuilder()
->addSelect('product_category.id')
->from('Pim\Component\Catalog\Model\Product', 'product')
->join('product.categories', 'product_category');
在我的主要查询中:
$qb->andWhere($qb->expr()->in('category.id', $qb2->getDQL()));
感谢 Alexandru Cosoi 和 Stmm 提供的有用信息!
我正在使用 Symfony 2、Doctrine 和 Query Builder。 我有 2 tables:产品和类别。
产品 ORM 文件包含以下内容:
manyToMany:
categories:
targetEntity: Pim\Component\Catalog\Model\CategoryInterface
joinTable:
name: pim_catalog_category_product
joinColumns:
product_id:
referencedColumnName: id
onDelete: CASCADE
inverseJoinColumns:
category_id:
referencedColumnName: id
onDelete: CASCADE
这样做的效果是,我有一个名为 "pim_catalog_category_product" 的 table 链接类别和产品。 我的类别 ORM 文件中没有关于产品的信息。
我正在尝试使用 QueryBuilder 构建查询,但我不明白如何从类别 table 的查询开始,该类别链接产品以便在产品上添加一些过滤器。
$qb = $this->getEntityManager()
->createQueryBuilder()
->addSelect('category')
->from($this->_entityName, 'category')
->join('Pim\Component\Catalog\Model\Product', 'product', 'WITH', 'category.id IN (product.categories);
但现在我收到以下错误:
Expected Literal, got 'product' at ... SELECT category FROM Pim\Bundle\CatalogBundle\Entity\Category category INNER JOIN Pim\Component\Catalog\Model\Product product WITH category.id IN (product.categories) at ...
有人可以帮助我吗?谢谢。
当你使用 ManyToMany 学说时,在后台为你做了很多关于关系管理的事情 'magic',这样你就可以进行快速连接,而无需考虑连接的笛卡尔积
$this->getEntityManager()
->createQueryBuilder()
->addSelect('product')
->from($this->_entityName, 'p')
->join('p.category')
或像
这样的快速冲洗$product->setCategories($categories);
$em->persist($product);
$em->flush();
缺点是,为了让 doctrine 能够做到这一点 'magic' 您无权访问内部联接 table 您需要执行所需的联接.
此外,如果您不在 'category' 上定义反向关系,我认为学说无法为您管理此连接。但请注意,如果您有很多产品,这样做会产生很大的内存开销,因为 doctrine 会延迟加载您类别中的所有产品。
如果您不想定义反向关系(由于上述问题),解决方法是在您的关系 table 上定义一个实体(类似于 ProductCategory),然后定义2 此实体的 2 列上的 1->1 关系。然后,只要您想创建从类别开始并加入产品的查询构建器,就可以使用此实体作为桥梁,而无需在类别
上定义 M<->M 关系类似于
$qb = $this->getEntityManager()
->createQueryBuilder()
->addSelect('c')
->from($this->_entityName, 'c')
->join('Pim\Component\Catalog\Model\ProductCategory', 'pc', 'WITH', 'c.id = pc.category_id')
->join('Pim\Component\Catalog\Model\Product', 'p', 'WITH', 'p.id = pc.product_id')
PS:尝试像上面的例子一样使用短别名,以避免更多的 "literal" 异常。
希望对您有所帮助,
亚历山德鲁·科索伊
我终于设法通过子查询和从 ManyToMany 关系加入 table 的正确方法解决了我的问题。
$qb2 = $this->getEntityManager()
->createQueryBuilder()
->addSelect('product_category.id')
->from('Pim\Component\Catalog\Model\Product', 'product')
->join('product.categories', 'product_category');
在我的主要查询中:
$qb->andWhere($qb->expr()->in('category.id', $qb2->getDQL()));
感谢 Alexandru Cosoi 和 Stmm 提供的有用信息!