19

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

分离:

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

合并:

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

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

4

3 回答 3

23

我应该何时分离实体?
当您处理多个 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加载的对象。$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 ”(lvl 90)使用的 AttackOne 将被比“UserBarr”(lvl 20)使用的更好的奖励修改,但在我们的数据库中,AttackOne始终是相同的攻击

于 2016-07-04T17:10:04.697 回答