Doctrine2 Entites - 是否可以将"脏"对象与数据库中的对象进行比较

Dav*_*cea 6 php symfony doctrine-orm doctrine-odm

是否可以比较当前"脏"版本(具有某些属性已更改但尚未保留的对象)与"原始"版本(数据仍在数据库中)之间的实体对象的状态.

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

$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)));
}
Run Code Online (Sandbox Code Playgroud)

但根据我的经验,$ entity和$ db_entity始终是相同的对象(并且在$ request bind形式之后具有与$ entity相同的数据).有没有办法得到一个新的版本的$实体和"脏"版本为了比较的缘故?我见过的解决方案都会在表单绑定发生之前提取所需的数据,但我宁愿没有这个限制.

更新:为了澄清,我不仅要查看实体属性的更改,还要查看其相关的实体集合.

Gma*_*let 9

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

// Run these AFTER persist and BEFORE flush
$uow = $em->getUnitOfWork();
$uow->computeChangeSets();
$changeset = $uow->getEntityChangeSet($entity);
Run Code Online (Sandbox Code Playgroud)

  • 请务必在这篇文章中阅读与此方法相关的警告:http://stackoverflow.com/questions/9057558/is-there-a-built-in-way-to-get-all-of-the-changed-更新字段-IN-A-学说-2 (2认同)

Ale*_*lex 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;
Run Code Online (Sandbox Code Playgroud)

你可能也想读这个:实现唤醒或克隆