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

gre*_*emo 18 orm doctrine doctrine-orm

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

分离:

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

合并:

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

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

man*_*nix 20

什么时候应该拆分实体?
当您处理多个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();
Run Code Online (Sandbox Code Playgroud)

您无法控制$user对象,$em2因为它的会话属于$em最初加载$user来自数据库的会话.他们如何解决上面的问题?您需要分离对象:

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

$em2->detach($user);
$em2->remove($user);
$em2->flush();
Run Code Online (Sandbox Code Playgroud)

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

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

$em->merge($user);
$em->flush();  
Run Code Online (Sandbox Code Playgroud)

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

flush方法触发提交,用户名将在数据库中更新

  • 这是一个很好的解释(+1),但为什么一开始应该使用多个实体管理器?无法得到它,抱歉,使用Doctrine始终与一个实体经理... (2认同)