为什么需要在ORM中分离和合并实体?

时间:2012-11-18 14:41:36

标签: orm doctrine doctrine-orm

问题是关于Doctirne,但我认为可以扩展到许多ORM。

分离:

  

实体与EntityManager分离,因此不再受管理   通过调用EntityManager#detach($entity)方法或通过   将分离操作级联到它。对分离的更改   实体,如果有的话(包括删除实体),将不会   分离实体后同步到数据库。

合并:

  

合并实体是指(通常是分离的)实体的合并   进入EntityManager的上下文,以便它们被管理   再次。要将实体的状态合并到EntityManager中,请使用   EntityManager#merge($entity)方法。被传递实体的状态   将合并到此实体的托管副本,此副本将   随后被退回。

我(几乎)理解这是如何工作的,但问题是:为什么需要分离/合并来源?当这两个操作可以使用/需要时,你能给我一个例子/场景吗?

3 个答案:

答案 0 :(得分:18)

我应该何时拆分实体?
当您处理多个EM并避免并发冲突时,广泛使用从EM(EntityManager)中分离实体,例如:

$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的{​​{1}}。他们如何解决上面的问题?您需要分离对象:

$user

我应该何时使用合并功能?
基本上,当您想要更新实体时:

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

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

EM将对数据库中的$ user与内存中的$ user进行比较。一旦EM识别出已更改的字段,它只会更新它们并保留旧字段。

$user= $em->find('models\User', 1); $user->setName('Foo'); $em->merge($user); $em->flush(); 方法触发提交,用户名将在数据库中更新

答案 1 :(得分:1)

在处理并发问题时,您需要分离实体。

假设您正在使用异步API来回调项目。当您发出API调用以及回调指令时,您可能仍在管理受回调影响的实体,因此会覆盖回调所做的更改。

答案 2 :(得分:0)

您还可以在数据库中包含pernamently数据时分离实体,但在代码中,您可以根据用户帐户修改此实体。

例如浏览器游戏中有一些角色和一些攻击。 AttackOne 由" UserFoo" (lvl 90)将被更好的奖金修改而不是" UserBarr" (lvl 20),但在我们的数据库中 AttackOne 一直都是同样的攻击