Php 用条令2中的所有相关实体填写部分集合

Php 用条令2中的所有相关实体填写部分集合,php,doctrine-orm,doctrine,Php,Doctrine Orm,Doctrine,假设我有以下查询,该查询返回一个用户实体,其中包含已标记的关联Post实体(这只是为了演示): 一旦我使用了它,我就想访问该用户的所有帖子,不管isFlagged是什么。是否有一种简单的方法来刷新$user->posts集合,使其成为所有用户帖子的完整集合 我不想只取出查询中的所有帖子(因为它们可能不需要),需要完整集合的代码也不会知道该实体来自哪个查询。您在这里所做的工作已被破坏: SELECT u, p FROM User u JOIN u.posts p W

假设我有以下查询,该查询返回一个用户实体,其中包含已标记的关联Post实体(这只是为了演示):

一旦我使用了它,我就想访问该用户的所有帖子,不管isFlagged是什么。是否有一种简单的方法来刷新
$user->posts
集合,使其成为所有用户帖子的完整集合


我不想只取出查询中的所有帖子(因为它们可能不需要),需要完整集合的代码也不会知道该实体来自哪个查询。

您在这里所做的工作已被破坏:

SELECT
    u, p
FROM
    User u
JOIN
    u.posts p
    WITH
    p.isFlagged = true
这将使“User#posts”集合具有错误的值,从而导致逻辑中断、对象图中断和所有内容中断

您应该在DQL级别通过以下方式解决此问题:

SELECT
    u, p
FROM
    User u
JOIN
    u.posts p
JOIN
    u.posts j
    WITH
    j.isFlagged = true
这将基本上在用户对象中创建正确的posts集合,没有任何中间(中断)状态

编辑:我误解了这个问题,因为我的想法基于@Athlan的答案,这是根本错误的(刷新一个损坏的集合是非常错误的)。这是我以前的答案,我仍然认为它很有趣,因为它解决了问题,但不是以一种真正正确的方式

这个问题实际上让我好奇,看看ORM是否像我预期的那样刷新了集合

基本上,您需要做的只是:

$entityManager->refresh($entity);
以下是测试的相关部分:

$foo=新的DDC2666Foo();
$this->\u em->persist($foo);
$this->_em->flush();
$this->_em->clear();
$fetchedFoo=$this->\u em->find(\u\u名称空间\u.'\DDC2666Foo',$foo->id);
$fetchedFoo->bar->add(新DDC2666Bar());
$this->assertCount(1$fetchedFoo->bar);
$this->_em->刷新($fetchedFoo);
$this->assertCount(0,$fetchedFoo->bar,“集合已重置”);
缺点是这也会重新获取实体,但ORM本身不提供刷新单个集合的外观


无论如何,这也是一件好事,因为这样,您就不会破坏封装,这可能会导致代码中出现意外的(难以调试的)行为。

您在这里所做的工作被破坏了:

SELECT
    u, p
FROM
    User u
JOIN
    u.posts p
    WITH
    p.isFlagged = true
这将使“User#posts”集合具有错误的值,从而导致逻辑中断、对象图中断和所有内容中断

您应该在DQL级别通过以下方式解决此问题:

SELECT
    u, p
FROM
    User u
JOIN
    u.posts p
JOIN
    u.posts j
    WITH
    j.isFlagged = true
这将基本上在用户对象中创建正确的posts集合,没有任何中间(中断)状态

编辑:我误解了这个问题,因为我的想法是基于@Athlan的答案,这是根本错误的(刷新一个损坏的集合是非常错误的)。这是我以前的答案,我仍然认为它很有趣,因为它解决了问题,但不是以一种真正正确的方式

这个问题实际上让我好奇,看看ORM是否像我预期的那样刷新了集合

基本上,您需要做的只是:

$entityManager->refresh($entity);
以下是测试的相关部分:

$foo=新的DDC2666Foo();
$this->\u em->persist($foo);
$this->_em->flush();
$this->_em->clear();
$fetchedFoo=$this->\u em->find(\u\u名称空间\u.'\DDC2666Foo',$foo->id);
$fetchedFoo->bar->add(新DDC2666Bar());
$this->assertCount(1$fetchedFoo->bar);
$this->_em->刷新($fetchedFoo);
$this->assertCount(0,$fetchedFoo->bar,“集合已重置”);
缺点是这也会重新获取实体,但ORM本身不提供刷新单个集合的外观


不管怎样,这也是一件好事,因为这样,您就不会破坏封装,这可能会导致代码中出现意外的(难以调试的)行为。

我也遇到了同样的问题,并在这里结束了。刷新不是我的选择,因为我有一个列表,我不想做那些额外的查询

你在这里真正需要的是添加一个“假”连接来进行过滤,并保留原始连接不带任何条件。。。为了说明这一点:

SELECT u, p
FROM User u
LEFT JOIN u.posts p
LEFT JOIN u.posts p2
WHERE p2.isFlagged = true

请注意,我在select子句中省略了p2,这只是出于筛选目的。

我也遇到了同样的问题,最后出现在这里。刷新不是我的选择,因为我有一个列表,我不想做那些额外的查询

你在这里真正需要的是添加一个“假”连接来进行过滤,并保留原始连接不带任何条件。。。为了说明这一点:

SELECT u, p
FROM User u
LEFT JOIN u.posts p
LEFT JOIN u.posts p2
WHERE p2.isFlagged = true

请注意,我在select子句中省略了p2,这只是出于过滤目的。

我发现其他解决方案非常不令人满意,因为许多实体会得到我根本不感兴趣的水分。如果绝大多数帖子都
isFlagged=0
,那么对性能的影响是巨大的

这里有一个替代解决方案,涉及到围绕实体之间的关系进行交换。然而,它并不完全等同于原始问题的要求。然而,这对其他有此问题的人可能有用:

SELECT p, u
FROM Post p
JOIN p.user u
WHERE p.isFlagged = true

此解决方案与其他解决方案的区别在于,它将不再返回没有任何帖子或任何标记帖子的用户。这可能是你想要的,也可能不是你想要的。

我发现其他解决方案非常不令人满意,因为许多实体会得到我根本不感兴趣的水分。如果绝大多数帖子都
isFlagged=0
,那么对性能的影响是巨大的

这里有一个替代解决方案,涉及到围绕实体之间的关系进行交换。然而,它并不完全等同于原始问题的要求。然而,这对其他有此问题的人可能有用:

SELECT p, u
FROM Post p
JOIN p.user u
WHERE p.isFlagged = true
此解决方案与其他解决方案的区别在于,它不再返回执行此操作的用户