2011-12-05 17 views
1

私はpropel ORMを使ってsymfonyプロジェクトに取り組んでいます。私のモデルでは、私はその要素が別のテーブル(リンクテーブル)によって、同じテーブルの多くの要素とリンクすることができるテーブルを持っています。いくつかのコードは、より良い説明します:基準双方向結合?

table1: 
    id_element: integer; 
    [...] 

とリンクテーブル:

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

私は私に特定の要素を持つすべての関連要素を返すPropelの基準でクエリを構築する必要があります。問題は、私が指定したい要素は、リンクテーブルのid2フィールドのようにid1フィールドのようにすることができるということです。

今、私の基準定義コード(明らかに動作していない)

$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は、1に参加しますリンクテーブルの各側に? 「or-join」を実行する方法はありますか?私を助けてください!

は、たぶん私はよくあなたが必要とするものを理解していない:)

+0

多分あなたは解決策を考えるべきです。この種の再帰的な動作はリレーショナルデータベースでは推奨されません。あなたは、このモデルが何を表現しようとしているかについてもう少し詳しく知ることができますか?ほとんどの場合、私は複雑なクエリで自分自身を見つけることができます。これは、ほとんどの場合、問題が解決したとは思えませんでした。 – guiman

+0

以下の表はプロセスを表しています。これらのプロセスは他のプロセスと関連していて、そこに多面的な関係が形成されていて、この関係はリンクテーブルとして実装されなければなりません。 –

答えて

0

最後に、私は基準を使用してそれを行うための方法を見つけた:

$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); 

そうでないかもしれない最良の方法が、作業罰金。

ご回答ありがとうございます。

+1

ループ内の不必要なハイドレーションは、繰り返し回数に応じてこのクエリをかなり遅くします。このようにしたい場合は、4行目と10行目の 'doSelect'を' doSelectStmt'(そして各ループの内部で必要な調整を行います)と入れ替えます。 – halfer

0

...あなたは2つの外部の両方に同じテーブルにリンクされているテーブルのキー、およびそのIDを持っているあなたの時間をありがとうございましたあなたは、or-joinを望みます。なぜ2つの基準と2つの選択肢に分割しないのですか?

+0

私の選択操作の結果、テーブル内にユニークなエンティティの配列が必要となるためです。 –

0

ただ、声に出しを考える - これと機能的に同じに見えること:

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で推奨されなくなると思われたら、それを先取りすることをお勧めします。