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

时间:2021-08-13 06:48:07

Is it possible to compare the state of an entity object between the current "dirty" version (an object that has some of its properties changed, not yet persisted) and the "original" version (the data still in the database).

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

My assumption was that I could have a "dirty" object, then pull a fresh one from the DB and compare the two. For instance:

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

$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)));
}

But in my experience, $entity and $db_entity are always the same object (and have the same data as $entity, after the form $request bind). Is there a way to get a fresh version of the $entity alongside the "dirty" version for comparison's sake? The solutions I've seen all pull the needed data before the form bind happens, but I'd rather not have that limitation.

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

Update: To clarify, I'm looking not only for changes to the entities' properties but also its related collections of entities.

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

2 个解决方案

#1


6  

After you flush the $em it happens (it is commited) in database.. so... you might want to retrieve the $db_entity before flush()

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


  1. I am not sure what you want.. but you can also use merge instead of persist.

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

    • merge is returning the object modified - id generated and setted
    • merge返回修改后的对象 - 生成和设置的id
    • persist is modifying your instance
    • persist正在修改你的实例
  2. If you want to have the object modified and not persisted use it before flush.

    如果您想要修改对象而不是持久化,请在刷新之前使用它。

  3. EntityManager is giving you the same instance because you didn't $em->clear()
    • flush is commiting all changes (all dirty objects)
    • flush是提交所有更改(所有脏对象)
    • clear is clearing memory cache. so when you find(..., $id) , you will get a brand new instance
    • 清除是清除内存缓存。所以当你找到(...,$ id)时,你会得到一个全新的实例
  4. EntityManager为您提供相同的实例,因为您没有$ em-> clear()flush提交所有更改(所有脏对象)清除是清除内存缓存。所以当你找到(...,$ id)时,你会得到一个全新的实例
  5. Is clone keyword working for you? like in this example:
  6. clone关键字是否适合您?像在这个例子中:

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

And you might also want to read this: Implementing Wakeup or Clone

您可能还想阅读此内容:实施唤醒或克隆

#2


9  

You can get what has changed on the entity through Doctine's UnityOfWork. It is quite simple : after you persisted the entity, Doctrine knows what to update in the database. You can get these informations by doing :

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

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

#1


6  

After you flush the $em it happens (it is commited) in database.. so... you might want to retrieve the $db_entity before flush()

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


  1. I am not sure what you want.. but you can also use merge instead of persist.

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

    • merge is returning the object modified - id generated and setted
    • merge返回修改后的对象 - 生成和设置的id
    • persist is modifying your instance
    • persist正在修改你的实例
  2. If you want to have the object modified and not persisted use it before flush.

    如果您想要修改对象而不是持久化,请在刷新之前使用它。

  3. EntityManager is giving you the same instance because you didn't $em->clear()
    • flush is commiting all changes (all dirty objects)
    • flush是提交所有更改(所有脏对象)
    • clear is clearing memory cache. so when you find(..., $id) , you will get a brand new instance
    • 清除是清除内存缓存。所以当你找到(...,$ id)时,你会得到一个全新的实例
  4. EntityManager为您提供相同的实例,因为您没有$ em-> clear()flush提交所有更改(所有脏对象)清除是清除内存缓存。所以当你找到(...,$ id)时,你会得到一个全新的实例
  5. Is clone keyword working for you? like in this example:
  6. clone关键字是否适合您?像在这个例子中:

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

And you might also want to read this: Implementing Wakeup or Clone

您可能还想阅读此内容:实施唤醒或克隆

#2


9  

You can get what has changed on the entity through Doctine's UnityOfWork. It is quite simple : after you persisted the entity, Doctrine knows what to update in the database. You can get these informations by doing :

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

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