PHP Doctrine:测试 object 是否在 ArrayCollection 中

PHP Doctrine : Test if an object is in an ArrayCollection

我正在尝试使用方法 ArrayCollection::contains 来查找 object 是否已经在我的 Collection 中,但是当我这样做时:

//My ArrayCollection
$lesRoles = $drt->getDrtApplication()->getRoles();
$leRole = $lesRoles->first();
echo "Property appNom : ".$leRole->getRleApplication()->getAppNom()."// Property appRole : ".$leRole->getRleId()." <br>";


$role = new \Casgaya\Role(2,$drt->getDrtApplication());
echo "Property appNom : ".$role->getRleApplication()->getAppNom()."// Property appRole : ".$role->getRleId()." <br>";

var_dump($lesRoles->contains($role));

结果是:
属性 appNom:CORA// 属性 appRole:2
属性 appNom:CORA// 属性 appRole:2
布尔(假)

由于 appNom 和 rleId 是实体 Role 拥有的仅有的两个属性,我希望它 return 正确。

编辑新测试用例:

echo "Test object role :  <br>";
var_dump($lesRoles==$role);
echo"<br>";
echo "Test integer property rleID from object role :  <br>";
var_dump($role->getRleId() == $leRole->getRleId());
echo"<br>";
echo "Test Application object property RleApplication from object role : <br> ";
var_dump($role->getRleApplication() == $leRole->getRleApplication());

结果是:

属性 appNom:CORA// 属性 appRole:2
属性 appNom:CORA// 属性 appRole:2
测试object角色:
布尔(假)
测试整数 属性 来自 object 角色的 rleID :
布尔(真)
测试应用程序 object 属性 来自 object 角色的 RleApplication :
布尔(真)

请注意,当我测试两个属性是否相等时,它们都为真。但是当我测试两者的相等性时 object,它是错误的。

所以问题不再是关于 ArrayCollection::contains,而是:
在相等的情况下比较两个学说实体的标准是什么?

contains( mixed $element ) Checks whether the given element is contained in the collection. Only element values are compared, not keys. The comparison of two elements is strict, that means not only the value but also the type must match. For objects this means reference equality.

来源: http://www.doctrine-project.org/api/common/2.1/class-Doctrine.Common.Collections.ArrayCollection.html

如果你想检查某个角色是否包含在集合中,你可以通过 Doctrine 检索它 - 它会 return 相同的对象,因为 Doctrine 通常不会获取已经通过另一个查询获取的实体.

我自己找到了解决办法,这里是给有同样问题的人:

我正在使用方法 ArrayCollection::exists 而不是包含方法,因此我可以指定应根据哪些标准建立对象之间的相等性:

就我而言:

$result = $lesRoles->exists(function($key,$element) use ($role) 
{
    return ($element->getRleApplication() == $role->getRleApplication() && $role->getRleId() == $element->getRleId());
});

注意这里$key和$element是从集合中测试的当前对象

我遇到了同样的问题:

$Xrepository->removeX($x);
$x->getY()->removeXRelation($x);

removeXXXRelation() 我测试了 ArrayCollection->contains()
是否存在关系 这 contains() 会失败

经过 2 小时的调试和尝试,解决方案是这样的

$x->getY()->removeXRelation($x);
$Xrepository->removeX($x);

简单地翻转删除调用。

如您所见,Doctrine 正在对对象施展魔法。
这个魔法从 remove 调用开始。
一位同事告诉我有关休眠对象生命周期状态的信息,这些状态解析为:
不持久、持久和不再持久
由于生命周期状态的变化,您的对象可能会生成两次,从而使 contains() 变为错误(包含检查对象身份)
这是我的理论(如果我错了请告诉我)