19

質問は Doctrine に関するものですが、多くの ORM に拡張できると思います。

切り離す:

エンティティは EntityManager から切り離されているため、そのエンティティでEntityManager#detach($entity)メソッドを呼び出したり、切り離し操作をカスケードしたりしても管理されなくなります。デタッチされたエンティティに加えられた変更 (エンティティの削除を含む) がある場合、エンティティがデタッチされた後はデータベースに同期されません。

マージ:

エンティティのマージとは、(通常は切り離された) エンティティを EntityManager のコンテキストにマージして、再び管理されるようにすることです。エンティティの状態を EntityManager にマージするには、 EntityManager#merge($entity)メソッドを使用します。渡されたエンティティの状態は、このエンティティのマネージド コピーにマージされ、その後、このコピーが返されます。

私はこれがどのように機能するかを(ほぼ)理解していますが、問題は、エンティティを切り離したりマージしたりする必要があるのはなぜですか?これらの 2 つの操作を使用できる/必要な場合の例/シナリオを教えてください。

4

3 に答える 3

23

いつエンティティをデタッチする必要がありますか?
EM (EntityManager) からのエンティティのデタッチは、複数の EM を処理し、同時実行の競合を回避する場合に広く使用されます。次に例を示します。

$user= $em->find('models\User', 1);
$user->setName('Foo');

// You can not remove this user, 
// because it still attached to the first Entity Manager
$em2->remove($user);
$em2->flush();

オブジェクトのセッションは最初にデータベースからロードするものに属しているため、$userオブジェクトを制御することはできません。上記の問題を解決する方法は?最初に元のオブジェクトからデタッチする必要があります。$em2$em$user$em

$user= $em->find('models\User', 1);
$user->setName('Foo');

$em->detach($user);
$em2->remove($user);
$em2->flush();

マージ機能はいつ使用する必要がありますか?
基本的に、エンティティを更新する場合:

$user= $em->find('models\User', 1);
$user->setName('Foo');

$em->merge($user);
$em->flush();  

EM は、データベース内の $user とメモリ内の $user を比較します。EM は、変更されたフィールドを認識すると、それらを更新するだけで、古いフィールドを保持します。

flushメソッドがコミットをトリガーし、ユーザー名がデータベースで更新されます

于 2012-11-18T17:03:57.120 に答える
1

同時実行の問題を処理する場合は、エンティティをデタッチする必要があります。

プロジェクトへのコールバックを行う非同期 API を使用しているとします。コールバック命令とともに API 呼び出しを発行すると、コールバックの影響を受けるエンティティを管理している可能性があるため、コールバックによって行われた変更が上書きされます。

于 2014-03-07T13:49:01.377 に答える
0

データベースに永続的なデータがある場合はエンティティを切り離すこともできますが、コードでは、ユーザー アカウントに応じてこのエンティティを変更します。

たとえば、いくつかのキャラクターと戦うためのいくつかの攻撃があるブラウザゲーム。" UserFoo " (レベル 90) が使用する AttackOne は、"UserBarr" (レベル 20) が使用するよりも優れたボーナスによって変更されますが、データベースでは、 AttackOneは常に同じ攻撃です。

于 2016-07-04T17:10:04.697 に答える