Doctrine orm 在Doctrine2中保存单个实体

Doctrine orm 在Doctrine2中保存单个实体,doctrine-orm,Doctrine Orm,我可以在Symfony中保存单个实体,而不刷新所有更改吗?例如 $em = $this->getDoctrine(); $entity1 = $em->find('\SomeEntity', 1); $entity2 = $em->find('\SomeEntity', 2); $entity1->setFoo(1); $entity1->persist(); $entity2->setFoo(2); $this->saveRightNow($entit

我可以在Symfony中保存单个实体,而不刷新所有更改吗?例如

$em = $this->getDoctrine();
$entity1 = $em->find('\SomeEntity', 1);
$entity2 = $em->find('\SomeEntity', 2);
$entity1->setFoo(1);
$entity1->persist();
$entity2->setFoo(2);
$this->saveRightNow($entity2); // entity2 is written to the DB at this point
$em->flush(); // entity1 is written to the DB at this point
查看源代码,我似乎可以使用
原则\ORM\UnitOfWork::commit

function saveRightNow($entity) {
    $em = $this->getDoctrine();
    $uow = $em->getUnitOfWork();
    $uow->commit($entity);
}

但是我找不到任何关于以这种方式使用
commit
的文档(也找不到很多关于使用它的文档,尽管它没有标记为内部函数)。这是个好主意吗?有什么危险吗?

我们所有的实体都是名为Entity.php的超类的子类,该超类具有如下功能:

public function save($flush = TRUE)
{
    try {
        self::getEntityManager()->persist($this);

        if ($flush) {
            self::getEntityManager()->flush();
        }
    } catch (\Exception $e) {
        return $e;
    }

    return TRUE;
}
$em = $this->getDoctrine();
$entity1 = $em->find('\SomeEntity', 1);
$entity2 = $em->find('\SomeEntity', 2);
$entity1->setFoo(1);
$entity2->setFoo(2);

// At this point start the "new" code
// So, first detach $entity2
$em->detach($entity2); // Now the EntityManager doesn't know anymore of $entity2
$em->flush(); // entity1 is written to the DB at this point

// Add again $entity2 to the EntityManager
$em->persist($entity2);
$em->flush();

可以通过您最喜欢的方式提供对getEntityManager的引用来获取EntityManager(我们将我们的内容保存到Zend_注册表中)。

此外,如果这是一个老问题,也许回复对其他人有用,因为这是Google显示的第一个问题

因此,您不能
刷新
单个实体,但可以
分离它们

因此,在您的特定情况下,您可以这样做:

public function save($flush = TRUE)
{
    try {
        self::getEntityManager()->persist($this);

        if ($flush) {
            self::getEntityManager()->flush();
        }
    } catch (\Exception $e) {
        return $e;
    }

    return TRUE;
}
$em = $this->getDoctrine();
$entity1 = $em->find('\SomeEntity', 1);
$entity2 = $em->find('\SomeEntity', 2);
$entity1->setFoo(1);
$entity2->setFoo(2);

// At this point start the "new" code
// So, first detach $entity2
$em->detach($entity2); // Now the EntityManager doesn't know anymore of $entity2
$em->flush(); // entity1 is written to the DB at this point

// Add again $entity2 to the EntityManager
$em->persist($entity2);
$em->flush();
显然,这是一个非常简单的例子

在实际用例中,您可能已将2个以上的实体加载到EntityManager中。在这种情况下,如果
detach($entity2)
,则具有第一个
flush()
的EntityManager也可能会将对其他加载实体所做的修改保存到数据库中

因此,必须小心使用此解决方案

另一种解决方案可能是使用
clear()
:这将分离所有托管实体。它与刚刚初始化的新EntityManager非常相似

我最近使用了最后一个解决方案,仅保存实体的部分数据,该实体具有一些不需要保存的相关实体

因此,我:

  • 首先清除实体经理
  • 然后重新加载我正在更新的实体
  • 作出相关修改
  • 让整个管理者脸红
  • 进行非常具体的刷新可能有点复杂,当然,如果有一个只保存部分实体的方法,那将非常有用


    但目前这些方法是唯一可行的。

    这可能是一个糟糕的想法。如果我不理解你到底想解决什么问题,我就不能说更多了。我怀疑您遗漏了doctrine为您所做的一些事情,并且正在尝试解决一个不存在的问题,或者是库预期的问题。基本上,我希望实体能够保存自己,这样某些DB更改可以在模型代码的深处完成,而无需控制器的程序员关心。timdev,使用单实体提交的原因是:1)避免启动有时成本高昂的变更跟踪过程;2) 将某些实体更改提交到单独的事务中;3) 为了控制提交到数据库的顺序,这与问题描述的完全不同。如果不刷新所有已保存的更改,则无法刷新一个已保存的更改。