#mapping #left-join #doctrine-orm #many-to-one
#сопоставление #левое соединение #doctrine-orm #соотношение многих к одному
Вопрос:
Я пытаюсь выбрать соответствующую строку в таблице product_item_sortorder на основе ProductID и toolboxItemId из таблицы product_item.
В обычном SQL это было бы для данного ProductID:
SELECT pi.*, pis.* FROM product_item pi
LEFT JOIN product_item_sortorder pis
ON pi.productId = pis.productId
AND pi.toolboxItemId = pis.toolboxItemId
WHERE pi.productId = 6
Я написал для него DQL следующим образом:
$this->_em->createQuery(
'SELECT pi
FROM EntitiesProductItem pi
LEFT JOIN pi.sequence s
WHERE pi.product = ?1'
);
Затем я получаю следующий SQL, если я вывожу $query->getSQL():
SELECT p0_.id AS id0, p0_.productId AS productId1, p0_.priceGroupId AS priceGroupId2, p0_.toolboxItemId AS toolboxItemId3, p0_.levelId AS levelId4, p0_.parentId AS parentId5, p0_.productId AS productId6, p0_.toolboxItemId AS toolboxItemId7 FROM product_item p0_ LEFT JOIN product_item_sortorder p1_ ON p0_.productId = p1_. AND p0_.toolboxItemId = p1_. WHERE p0_.productId = ? ORDER BY p0_.id ASC
Как вы можете видеть, указанные имена столбцов не найдены:
LEFT JOIN product_item_sortorder p1_ ON p0_.productId = p1_. AND p0_.toolboxItemId = p1_.
Подробная информация о таблице product_item:
----- ----------- ---------------
| id | productId | toolboxItemId |
----- ----------- ---------------
| 467 | 1 | 3 |
| 468 | 1 | 10 |
| 469 | 1 | 20 |
| 470 | 1 | 4 |
| 471 | 1 | 10 |
----- ----------- ---------------
Подробная информация о таблице product_item_sortorder:
----- ----------- --------------- ----------
| id | productId | toolboxItemId | sequence |
----- ----------- --------------- ----------
| 452 | 1 | 3 | 1 |
| 457 | 1 | 4 | 6 |
| 474 | 1 | 20 | 4 |
----- ----------- --------------- ----------
Объект ProductItem
<?php
/**
* @Entity(repositoryClass="RepositoriesProductItem")
* @Table(name="product_item")
*/
class ProductItem
{
...
/**
* @ManyToOne(targetEntity="ProductItemSortorder")
* @JoinColumns({
* @JoinColumn(name="productId", referencedColumnName="productId"),
* @JoinColumn(name="toolboxItemId", referencedColumnName="toolboxItemId")
* })
*/
protected $sequence;
...
?>
Объект ProductItemSortOrder
<?php
/**
* @Entity(repositoryClass="RepositoriesProductItemSortorder")
* @Table(name="product_item_sortorder")
*/
class ProductItemSortorder
{
...
/**
* @ManyToOne(targetEntity="Product")
* @JoinColumn(name="productId", referencedColumnName="id")
*/
protected $product;
/**
* @ManyToOne(targetEntity="ToolboxItem")
* @JoinColumn(name="toolboxItemId", referencedColumnName="id")
*/
protected $toolboxItem;
...
}
?>
Ответ №1:
Ваши сопоставления серьезно неверны. Вы используете ManyToOne на обоих концах, как это возможно? У вас обе ассоциации определены как на стороне «владельца», без сопоставления или инверсии (см. Главу «Сопоставления ассоциаций»). И вы используете столбцы объединения одной ассоциации для сопоставления со многими полями в другом объекте. Я полагаю, вы хотите сделать что-то еще, можете ли вы точно описать свой вариант использования?
Комментарии:
1. Я немного обновил вопрос, и ниже вы можете увидеть, какой запрос я хочу выполнить
Ответ №2:
Как бы вы сопоставили свой пример в YAML (поскольку пример @Hernan Rajchert представлен только в аннотациях):
ProductItem:
type: entity
manyToOne:
sequence:
targetEntity: ProductItemSortorder
joinColumns:
productId:
referencedColumnName: productId
toolboxItemId:
referencedColumnName: toolboxItemId