Критерии двунаправленного соединения? - PullRequest
1 голос
/ 05 декабря 2011

Я работаю над проектом Symfony с Propel ORM. В моей модели у меня есть таблица, в которой ее элементы могут быть связаны со многими элементами одной и той же таблицы другой таблицей (таблица ссылок). Некоторый код объяснит лучше:

table1:
    id_element: integer;
    [...]

и таблица ссылок:

 link_table:
     id1: fk to table1;
     id2: fk to table1;

Мне нужно создать запрос с Propel Criteria, который возвращает мне все связанные элементы с определенным элементом. Проблема в том, что элемент, который я хочу указать, может быть как в поле id1, так и в поле id2 таблицы ссылок.

теперь некоторые из моих кодов определения критериев (очевидно, не работают)

$c = new Criteria();
$c->addJoin($linkTable::ID1,$table::ID);
$c->addJoin($linkTable::ID2,$table::ID);
$c->addOr($linkTable::ID1,$specific_id);
$c->addOr($linkTable::ID2,$specific_id);
$result = $table->doSelect($c);

и это SQL-код, который я хочу сгенерировать:

SELECT * FROM table
    WHERE table.ID IN
        (SELECT link_table.ID1 FROM link_table
            WHERE link_table.ID2 = "the id that i want"
        )
    OR table.ID IN 
        (SELECT link_table.ID2 FROM link_table
            WHERE link_table.ID1 = "the id that i want"
        )

Так я должен сделать 2 соединения, по одному на каждую сторону таблицы ссылок? Есть ли способ сделать "or-join"? Пожалуйста, помогите мне!

Большое спасибо за потраченное время:)

Ответы [ 4 ]

0 голосов
/ 07 декабря 2011

наконец-то я нашел способ сделать это, используя критерии:

$c = new Criteria();
    $q1 = new Criteria();
    $q1->add($linkPeer::ID1,$my_value);
    result1 = $linkPeer->doSelect($q1);
    foreach($result1 as $result){
        ids1[] = $result->getID();
    }
    $q2 = new Criteria();
    $q2->add($linkPeer::ID2,$my_value);
    result2 = $linkPeer->doSelect($q2);
    foreach($result2 as $result){
        ids2[] = $result->getID();
    }
$ids = array_merge($ids1,$ids2);
$c->add($tablePeer::ID,$ids,Criteria::IN);
$totalResult = $tablePeer->doSelect($c);

возможно, не лучший способ, но работает нормально.

Большое спасибо за ваши ответы !!

0 голосов
/ 06 декабря 2011

Просто мысли вслух - это выглядит функционально идентично этому:

SELECT
    *
FROM
    my_table
LEFT JOIN
    link_table lt1 ON (lt1.id1 = my_table.id)
LEFT JOIN
    link_table lt2 ON (lt2.id2 = my_table.id)
WHERE
    lt1.id2 = X
OR
    lt2.id1 = X

Если это идентично (очевидно, проверьте), тогда это будет намного проще для создания запроса.Кроме того, попробуйте использовать ModelCriteria, если вы можете - я подозреваю, что критерии будут устаревшими в Propel 2, и это хорошая идея, чтобы планировать это заранее.

0 голосов
/ 07 декабря 2011

Избегайте использования Criteria, как сказал Halfer, лучше использовать ModelCriteria и его API. Прочитайте следующий документ для получения дополнительной информации: http://www.propelorm.org/reference/model-criteria.html

0 голосов
/ 06 декабря 2011

Может быть, я не совсем понимаю, что вам нужно ... у вас есть два внешних ключа таблицы, которые оба связаны с одной и той же таблицей, и, следовательно, id, и вы хотите присоединиться или присоединиться. Почему бы не разделить на два критерия и так два выбора?

...