Php 仅获取ID的列表';他来自许多人的教条
我有一个很多相关的领域,我在一个情况下,我只是试图获得所有的ID,而没有水合领域中的任何子实体 我知道在我访问该字段时,会有一个查询来获取实体引用,这很好。但是我需要通过ID循环,但是我不知道如何不做就获得它们Php 仅获取ID的列表';他来自许多人的教条,php,mysql,symfony,doctrine-orm,Php,Mysql,Symfony,Doctrine Orm,我有一个很多相关的领域,我在一个情况下,我只是试图获得所有的ID,而没有水合领域中的任何子实体 我知道在我访问该字段时,会有一个查询来获取实体引用,这很好。但是我需要通过ID循环,但是我不知道如何不做就获得它们 $ids = []; foreach($mainEntity->getSubEntities() as $subentity) { $ids[] = $subentity->getId(); } 由于foreach循环,这似乎也会自动水合子实体。这会导致大量不必要的查
$ids = [];
foreach($mainEntity->getSubEntities() as $subentity) {
$ids[] = $subentity->getId();
}
由于foreach
循环,这似乎也会自动水合子实体。这会导致大量不必要的查询,并影响页面加载时间
我还将子实体字段标记为extrallazy
/**
* @var ArrayCollection
* @ORM\ManyToMany(targetEntity="User", fetch="EXTRA_LAZY")
* @ORM\JoinTable(name="user_friends")
*/
protected $friends;
由于getKeys()只返回PersistentCollection的顺序索引,因此我发现以下oneliner解决方案:
$myCollectionIds = $myCollection->map(function($obj){return $obj->getId();})->getValues();
在环境中运行顺畅。我不相信用实体定义的方式做你想做的事情是可能的。Doctrine PersistentCollection类将始终初始化自身,当您在DB上迭代或映射时,从DB加载所有实体。它会在foreach循环或闭包中运行代码之前执行此操作,如和的实现中所示 即使将集合标记为,只要使用除contains、containsKey、count、get或slice以外的任何方法,内容都将从DB加载 然而,如果你不介意稍微调整你的实体结构,你可以得到你想要的行为 将多个关联合并为一个实体。 您的关系称为
朋友
,因此您可以建立一个友谊
实体:
/** @Entity */
class Frendship
{
/**
* @var int
* @Id @Column(type="integer") @GeneratedValue
**/
protected $id;
/**
* @var User
* @ORM\@ManyToOne(targetEntity="User", inversedBy="friendships")
**/
protected $friendA
/**
* @var User
* @ORM\@ManyToOne(targetEntity="User", inversedBy="friendships")
**/
protected $friendB
public function getOtherFriend(User $friend){
if ($this->friendA === $friend)) {
return $this->friendB;
} else if ($this->friendB === $friend)) {
return $this->friendA
} else {
throw new \Exception("$friend is not part of this friendship");
}
}
}
然后,您可以将您的friends
集合替换为frendships
集合,并对其进行迭代。友谊是完全水合的,但这没关系,因为它们只包含两个整数
您可以从每个友谊中获得另一个朋友,它将是一个代理对象,除非它碰巧已经被加载。由于您只想在其上调用
getId()
,因此不需要从数据库中检索完整的实体。这是否仍然会对集合中的所有实体进行水合作用?PersistentCollection继承了AbstractLazyCollection的映射,该死,你说得对。当map()-方法运行时,集合被初始化,即使只接收到ID。是的,我正在寻找一种方法,使集合只填充代理对象,但我没有找到。我对这个问题给出了不同的答案。我意识到我上面的代码不能很好地工作,因为用户类上的友谊关系需要mappedBy
的两个不同值,这是不可能的。不过,可能有类似的解决方案,可能是通过拥有两个单独的友谊集合,其中用户位于其中一个中所有友谊的A侧,而另一个中的友谊位于B侧。