从实体更新的Doctrine 2

Den*_*nis 43 php orm doctrine-orm

是否可以通过以下类似的方式更新实体:

$data       = new ATest();  // my entity
$data->id   = 1;            // id 1 already exists, I just want to update this row
$data->name = "ORM Tested"; // changed the name

$entityManager->persist($data);
$entityManager->flush();
Run Code Online (Sandbox Code Playgroud)

这将插入并更改对象的id,而不是更新数据库中的现有行.

Fra*_*ula 90

你应该调用merge而不是persist:

$data = new MyEntity();
$data->setId(123);
$data->setName('test');

$entityManager->merge($data);
$entityManager->flush();
Run Code Online (Sandbox Code Playgroud)

  • 他批准了自己的,有我的upvote! (8认同)
  • 我觉得有人在这里改变了他的答案,所以我看起来不再有用了...... (7认同)

Den*_*nis 53

我不得不使用

$entityManager->merge($data)
Run Code Online (Sandbox Code Playgroud)

  • 请注意,您应将其复制回$ data.即:`$ data = $ entityManager-> merge($ data)` (9认同)

Ton*_*nov 13

或者只是获取被管实体而不是空实体.

$data = $entityManager->getRepository('ATest')->findOne(1); // ATest is my entitity class
$data->name = "ORM Tested"; // just change the name

$entityManager->persist($data);
$entityManager->flush();
Run Code Online (Sandbox Code Playgroud)

如果实体已经被管理,则persist()将更新它而不是插入新实体.

  • 如果管理实体,则不需要调用persist,persist只是告诉doctrine开始管理实体.在这种情况下,冲洗就足够了. (7认同)
  • 这不是对数据库的双重查询只是为了更新吗? (3认同)
  • @Sejanus是的.我一直都在使用它,并希望知道一种更有效的方式. (3认同)
  • 实际上,是否需要持久性取决于配置 (2认同)
  • @Oshanz见[跟踪政策](http://doctrine-orm.readthedocs.org/projects/doctrine-orm/en/latest/reference/change-tracking-policies.html) (2认同)

fyr*_*rye 12

您还可以使用getReference按标识符更新实体属性而不检索数据库状态.

https://www.doctrine-project.org/projects/doctrine-orm/en/2.6/reference/advanced-configuration.html#reference-proxies

这将建立一个简单的代理,通过ID与Entity一起工作,而不是使用实例化new Entity或显式从数据库获取实体find(),然后可以通过flush更新.

$data = $entityManager->getReference('ATest', $id);
$data->setName('ORM Tested');
$entityManager->flush();
Run Code Online (Sandbox Code Playgroud)

这对于更新实体OneToManyManyToMany协会特别有用.例如:$case->addTest($data);

即使意图更新实体,手动设置新实体的标识符通常也是不好的做法.相反,通常最好让EntityManager或Entity构造函数建立适当的标识符,例如a UUID.因此,Doctrine默认会生成实体,标识符为私有属性,没有setter方法.

  • `Merge`将实体作为`Managed`附加到实体管理器.在OP案例中需要它的原因是该实体没有被管理`(独立)`.之所以发生这种情况,是因为它已经"实例化"并且从未被持久化/检索,因为它已经存在(根据OP).因此需要更新而不是持久性.所以在OP中,实体管理器试图持久化新对象,因为它已经存在,所以也无法执行,并且由于新对象不是"托管",因此也没有发生更新. (4认同)