PHP Doctrine:测试一个对象是否在ArrayCollection中

时间:2016-02-25 10:49:45

标签: php doctrine-orm contains equality arraycollection

我正在尝试使用方法ArrayCollection :: contains来查找对象是否已经存在于我的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自己正在跳的唯一两个属性,它将返回true。

编辑新测试案例:

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
测试对象角色:
布尔(假)
从对象角色测试整数属性rleID:
布尔(真)
从对象角色测试应用程序对象属性RleApplication:
布尔(真)

请注意,当我测试两个属性的相等性时,它们都是真的。但是,当我测试整个对象的相等性时,它是错误的。

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

3 个答案:

答案 0 :(得分:5)

我自己找到了解决方案,对于遇到同样问题的人来说,

我使用的方法是ArrayCollection :: exists而不是contains,所以我可以指定在哪个条件下建立对象之间的相等性:

就我而言:

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

请注意,此处$ key和$ element是从集合中测试的当前对象。

答案 1 :(得分:3)

  

包含(混合$元素)   检查给定元素是否包含在集合中。仅比较元素值,而不是键。两个元素的比较是严格的,这意味着不仅值而且类型必须匹配。 对于对象,这意味着引用相等。

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

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

答案 2 :(得分:0)

我遇到了同样的问题:

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

removeXXXRelation()中,我测试了该关系是否与ArrayCollection->contains()存在
contains()将会失败

经过2个小时的调试并尝试解决该问题的方法是这样的

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

只需翻转删除调用。

如您所见,Doctrine正在用物体做魔术。
此魔术始于删除调用。
一位同事告诉我有关休眠对象生命周期状态的信息,这些状态可以解决:
不再坚持,坚持和不再坚持
由于生命周期状态的更改,您的对象可能会生成两次,从而使contains()变为假(包含检查对象身份)
那是我的理论(如果我错了,请告诉我)