21

doctrineを使用しているときに、エンティティを削除するには、指定されたパラメータ(name、idなど)でそのエンティティを取得してから、removeメソッドを呼び出す必要があることに気付きました。一方、クエリでは、削除クエリを実行するだけです。

つまり、ORMスタイルを使用するには2つの操作が必要であり、一般的なSQL操作には1つの操作が必要であるように思われます。そのため、ORMで削除(または更新)操作を使用する必要があるかどうか、少し混乱していますか?パフォーマンスが悪いのではないですか?または私が欠けているものは他にありますか?ORMスタイルで他の方法で行うことはできますか?

4

2 に答える 2

42

Doctrine2では、データベースからロードされていないプロキシオブジェクトでdeleteを呼び出すことができます。次のような「ダミー」オブジェクトを作成するだけです。

$user = $em->getPartialReference('model\User', array('id' => $id));
$em->remove($user);

最初のクエリは必要ありませんが、Doctrineがフラッシュ時に内部的にクエリを実行するかどうかはよくわかりません。SqlLogに表示されません。

付け加えると、これはまともなORMの予想される動作だと思います。オブジェクトと関係を扱います。削除する前に、何かが存在することを知っている必要があります。ORMは単なるクエリジェネレータではありません。一般に、ネイティブクエリはどのORMでも常に高速になります。ORMは抽象化レイヤーを追加し、実行には時間がかかります。これは典型的なトレードオフであり、いくつかの優れた機能とクリーンなコードを取得できますが、パフォーマンスが低下します。

編集:

それがあなたのためにうまくいったことをうれしく思います。実際、私は別の問題に遭遇しました。その結果、プロキシと部分オブジェクトは実際には同じものではないことに気づきました。部分オブジェクトは実際のモデルクラスをインスタンス化し、必要な値で埋めます。部分オブジェクトを初期化すると、遅延読み込みは機能しなくなります。したがって、たとえば、IDのみで部分オブジェクトを作成し、別のオブジェクトフィールドが何らかの条件を満たす場合にのみ削除したい場合、他のフィールドは常にnullになるため、機能しません。

一方、プロキシは遅延読み込みで機能し、部分的なオブジェクトが抱える問題を共有しません。したがってgetPartialReference、メソッドを使用しないことを強くお勧めします。代わりに、次のようなことを行うことができます。

$user = $em->getReference('model\User', $id);
$em->remove($user);

このgetReferenceメソッドは、オブジェクトがすでにロードされている場合はオブジェクトを返し、ロードされていない場合はプロキシを返します。プロキシは、必要に応じて、他のすべての値を遅延ロードできます。あなたの例に関しては、それらはまったく同じように動作しますが、プロキシは確かにより良い方法です。

于 2012-07-14T20:45:13.083 に答える
5

終わり!私にとっては、この追加行3のように機能しました。

$user = $em->getReference('model\User', $id);
$em->remove($user);
$em->flush();
于 2015-12-02T18:23:25.757 に答える