问题是关于Doctirne,但我认为可以扩展到许多ORM。
分离:
实体与EntityManager分离,因此不再受管理 通过调用
EntityManager#detach($entity)
方法或通过 将分离操作级联到它。对分离的更改 实体,如果有的话(包括删除实体),将不会 分离实体后同步到数据库。
合并:
合并实体是指(通常是分离的)实体的合并 进入EntityManager的上下文,以便它们被管理 再次。要将实体的状态合并到EntityManager中,请使用
EntityManager#merge($entity)
方法。被传递实体的状态 将合并到此实体的托管副本,此副本将 随后被退回。
我(几乎)理解这是如何工作的,但问题是:为什么需要分离/合并来源?当这两个操作可以使用/需要时,你能给我一个例子/场景吗?
答案 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 一直都是同样的攻击