Doctrine2多对多加入表

时间:2015-04-21 17:58:34

标签: php sql doctrine-orm

我的架构如下所示:

items - item_id, ...
items_item_types - item_id, item_type_id
item_types - item_type_id, ...

我需要一个查询来获取包含所有项目类型的项目。例如,假设第1项是类型10,第2项是类型10,11和12.我给出了10和11,第1项将不会被退回,但第2项将是

进一步澄清:

--------------------------
| item_id | item_type_id |
| 1       | 10           |
| 2       | 10           |
| 2       | 11           |
| 2       | 12           |
--------------------------

我可以在SQL中轻松完成此操作,例如

select * from items 
    join item_item_types join_table1 on items.item_id = join_table1.item_id and join_table1.item_type_id = 10
    join item_item_types join_table2 on items.item_id = join_table1.item_id and join_table2.item_type_id = 11

在这种情况下会返回第2项

查询已经相当复杂了,我正在传递对QueryBuilder对象的引用,所以我不能使用本机SQL(据我所知)。我的代码是什么样的:

function addItemTypesToQuery(&$qb, $itemTypes) {
    foreach($itemTypes as $key => $value) {
        $qb->join('item.itemTypes', 'item_type' . $key, 'WITH', ???)
    }
}

我不确定镜像SQL需要什么连接条件。 Doctrine跳过了加入item_item_types表的中间步骤,但我需要在THAT上设置连接条件,而不是在item_types表上。

1 个答案:

答案 0 :(得分:0)

Doctrine将自动处理连接,并使用ItemType实体ID或实体引用搜索“多对多”表中的一组值。这是通过MEMBER OF DQL:

完成的
function addItemTypesToQuery(&$qb, $itemTypes) {
    $i = 0;
    foreach($itemTypes as $key => $value) {
        $qb->addWhere('?'.$i.' MEMBER OF item.itemTypes')
            ->setParameter($i++, $key)
        ;
    }
}

注意:我不知道您的QueryBuilder的父结构,但如果您已经使用数字标识符设置参数,则可能会遇到问题。一种选择是:

function addItemTypesToQuery(&$qb, $itemTypes) {
    $i = 0;
    foreach($itemTypes as $key => $value) {
        $qb->addWhere(':itemWhere'.$i.' MEMBER OF item.itemTypes')
            ->setParameter('itemWhere'.$i++, $key)
        ;
    }
}

请注意,$key 必须ItemType实体的主要标识符。如果它是实际的$value实体参考,您也可以使用ItemType