7

是否可以比较当前“脏”版本(其某些属性已更改但尚未持久化的对象)和“原始”版本(仍在数据库中的数据)之间的实体对象的状态。

我的假设是我可以有一个“脏”对象,然后从数据库中提取一个新对象并比较两者。例如:

$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 绑定形式之后具有与 $entity 相同的数据)。为了比较,有没有办法在“脏”版本旁边获得新版本的 $entity ?我见过的解决方案都是在表单绑定发生之前提取所需的数据,但我宁愿没有这个限制。

更新:为了澄清,我不仅在寻找对实体属性的更改,而且还在寻找其相关的实体集合。

4

2 回答 2

11

您可以通过 Doctine 的 UnityOfWork 获取实体上发生的变化。这很简单:在你持久化实体之后,Doctrine 知道要在数据库中更新什么。您可以通过以下方式获取这些信息:

// Run these AFTER persist and BEFORE flush
$uow = $em->getUnitOfWork();
$uow->computeChangeSets();
$changeset = $uow->getEntityChangeSet($entity);
于 2013-03-13T14:56:32.707 回答
7

在你刷新$em它之后它在数据库中发生(它被提交)......所以......你可能想要检索$db_entity之前flush()


  1. 我不确定你想要什么.. 但你也可以使用merge而不是persist.

    • merge正在返回修改的对象 - 生成和设置的 id
    • persist正在修改您的实例
  2. 如果您想修改对象并且persisted之前不使用它flush

  3. EntityManager给你同样的例子,因为你没有$em->clear()
    • flush正在提交所有更改(所有dirty对象)
    • clear正在清除内存缓存。所以当你find(..., $id),你会得到一个全新的实例
  4. clone关键字对您有用吗?就像在这个例子中:

$entity = $em->find('My\Entity', $id);
$clonedEntity = clone $entity;

您可能还想阅读以下内容:实现唤醒或克隆

于 2013-03-13T14:57:41.980 回答