是否可以比较当前“脏”版本(其某些属性已更改但尚未保留的对象)与“原始”版本(数据仍在数据库中)之间的实体对象的状态
我的假设是我可能有一个“脏”的对象,然后从数据库中提取一个新的对象并比较两者。例如:
$entity = $em->getRepository('MyContentBundle:DynamicContent')->find($id);
$editForm = $this->createContentForm($entity);
$editForm->bind($request);
if ($editForm->isValid()) {
$db_entity = $em->getRepository('MyContentBundle:DynamicContent')->find($id);
// compare $entity to $db_entity
$em->persist($entity);
$em->flush();
return $this->redirect($this->generateUrl('content_edit', array('id' => $id)));
}
但根据我的经验,$ entity和$ db_entity总是相同的对象(并且在$ request bind形式之后与$ entity具有相同的数据)。有没有办法得到一个新的版本的$实体和“脏”版本为了比较的缘故?我看到的解决方案都会在表单绑定发生之前提取所需的数据,但我宁愿没有这个限制。
更新:为了澄清,我不仅要查看实体属性的更改,还要查看相关的实体集合。
答案 0 :(得分:9)
您可以通过Doctine的UnityOfWork获取实体上发生的变化。这很简单:在您持久化实体之后,Doctrine知道要在数据库中更新的内容。您可以通过以下方式获取这些信息:
// Run these AFTER persist and BEFORE flush
$uow = $em->getUnitOfWork();
$uow->computeChangeSets();
$changeset = $uow->getEntityChangeSet($entity);
答案 1 :(得分:7)
刷新$em
后,它在数据库中发生(它已被提交)..所以......你可能想要在$db_entity
之前检索flush()
我不确定您想要什么......但您也可以使用merge
代替persist
。
merge
返回修改后的对象 - 已生成和已设置的ID persist
正在修改您的实例如果您想要修改对象而不是persisted
在flush
之前使用它。
EntityManager
为您提供相同的实例,因为您没有$em->clear()
flush
提交所有更改(所有dirty
个对象)clear
正在清除内存缓存。因此,当您find(..., $id)
时,您将获得一个全新的实例clone
关键字是否适用于您?就像在这个例子中一样:$entity = $em->find('My\Entity', $id);
$clonedEntity = clone $entity;
您可能还想阅读此内容:Implementing Wakeup or Clone