15

PHP 用の Doctrine ORM (v1.2) を試しています。クラス「酒」を定義し、2 つの子クラス「ジン」と「ウイスキー」を定義しました。私は具体的な継承 (ほとんどの文献ではクラス テーブルの継承) を使用して、クラスを 3 つの個別のデータベース テーブルにマップしています。

私は次のことを実行しようとしています:

$liquor_table = Doctrine_Core::getTable('liquor');
$liquors = $liquor_table->findAll();

当初、私は $liquors が、ウィスキーであろうとジンであろうと、すべての酒を含む Doctrine_Collection であることを期待していました。しかし、コードを実行すると、whisky および gin データベース テーブルに複数の行があるにもかかわらず、空のコレクションが得られます。生成された SQL に基づいて、理由がわかりました。ORM は、実際のデータが格納されているウイスキー/ジン テーブルではなく、「酒」テーブルをクエリしています。

継承タイプを列集計 (単純なテーブル継承) に切り替えると、コードが完全に機能することに注意してください。

すべての酒類を含む Doctrine_Collection を取得する最良の方法は何ですか?

アップデート

さらに調査した結果、Doctrine がUNION舞台裏で SQL 操作を実行して、"whisky" テーブルと "gin" テーブルからの結果セットを結合することを期待しているようです。

これは、ポリモーフィック クエリと呼ばれます。

このチケットによると、この機能は Doctrine 1.x では利用できません。これは 2.0 のリリースを予定しています。( CTIの Doctrine 2.0 ドキュメントも参照してください)。

この情報に照らして、この欠陥を回避するための最もクリーンで効率的な方法は何でしょうか? 単一テーブルの継承に切り替えますか? 2 つの DQL クエリを実行し、結果の Doctrine_Collections を手動でマージしますか?

4

2 に答える 2

3

現時点で Doctrine の唯一の安定した有用な継承モードは column_aggregation です。私はさまざまなプロジェクトで他のものを試しました。column_aggregation を使用すると、ポリモーフィック クエリを模倣できます。一般に、継承は Doctrine (1.x) では少しバグがあります。2.x ではこれが変更されるため、将来的にはより良いオプションが提供される可能性があります。

于 2010-08-12T07:04:08.087 に答える
0

しばらく前に、あなたが探していることを正確に実行する ORM の (本番環境に対応していない) 始まりを書きました。概念実証ができるように。私のすべての調査では、何らかの方法でコードとデータ (リキュール テーブルのサブクラス情報) が混在していることがわかりました。

したがって、リキュール クラス/テーブル クラスに独自のテーブルを照会するメソッドを作成することもできます。酒類クラスのすべてのサブクラスをハードコードする必要をなくす最善の方法は、サブクラスのクラス名を含む列を作成することです。

詳細をどのように広めるかは、完全にあなた次第です。最も正規化された (そして、ここで間違っている場合は誰でも訂正できます) 方法は、酒のクラスに表示されるすべてのフィールドを酒のテーブルに格納することだと思います。次に、サブクラスごとに、サブクラス タイプに関連する特定のデータを格納するテーブルを用意します。コードがリカー テーブルを読み取ってサブクラスの名前を取得し、結合を実行するため、これがコードとデータを混合するポイントです。

私の例では、車と自転車、およびそれらの間の最小限の、しかし些細な違いを使用します。

Ride
----
id
name
type

(1, 'Sebring', 'Car')
(2, 'My Bike', 'Bicycle')

Bicycle
-------
id
bike_chain_length

(2, '2 feet')

Car
---
id
engine_size

(1, '6 cylinders')

ここから先は、すべての酒類クラスのデータをサブクラス テーブルに格納し、参照とサブクラス名のみを酒テーブルに格納するなど、あらゆる種類のバリエーションがあります。ただし、共通データを集計している場合、共通フィールドについてすべてのサブクラス テーブルにクエリを実行する必要がなくなるため、これはあまり好きではありません。

お役に立てれば!

于 2010-08-09T15:41:54.440 に答える