简体   繁体   中英

Doctrine2 Many to Many Multiple Join on Table

My schema looks like this:

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

I need a query that will get items with ALL the item types given. For example, let's say item 1 is type 10, and item 2 is types 10, 11, and 12. I'm given 10 and 11, item 1 wouldn't be returned but item 2 would.

To clarify further:

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

I can do this easily in SQL, for example

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

Which would return item 2 in this case

The query is already quite complicated and I'm being passed a reference to the QueryBuilder object, so I cannot use native SQL (as far as I know). What my code looks like:

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

I'm not sure what the join condition needs to be to mirror the SQL. Doctrine skips over the intermediary step of joining the item_item_types table but I need to set join conditions on THAT, not on the item_types table.

Doctrine will handle the joins automatically and search a set of values in the Many-to-Many table using either the ItemType entity ID or entity reference. This is done with the MEMBER OF DQL:

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

Note: I don't know the parent structure of your QueryBuilder, but you could run into problems if you've already set parameters with the numeric identifiers. One alternative is:

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

Note that $key must be the primary identifier of the ItemType entity. You can also use $value if it's the actual ItemType entity reference.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM