Doctrine2:同步集合/添加一些可能已经存在的元素

时间:2012-04-27 12:01:34

标签: php doctrine-orm

所以我有一个字符串,代表几个对象(在这种情况下是标签) 即:“php,mysql,doctrine2” 假设我的数据库已经有“php”和“doctrine2”。 现在我想要最好的方法来添加缺少的元素(在这种情况下是mysql)。

我应该为每个元素创建一个对象,只使用persist / sync或者其他东西,还是有更好的方法?

无论如何,我还需要最后的所有对象将它们添加到一个新对象(具有简单的多对多关系)。

我对任何建议都很满意。

2 个答案:

答案 0 :(得分:2)

1)将所有标签名称通过单个查询拉出到数组中

2)使用array_filter和闭包来检测数据集中不存在的标签

3)为新标签创建插入

$currentTags = getCurrentTagsArray();
$newTags = explode(',', 'php,mysql,doctrine2');

$newTagsToSave = array_filter($currentTags, function($item) use ($newTags){
    if (in_array($item, $newTags))
    {
       return false;
    }
    return true;
});

或者...

您可以使用Doctrine 2的ArrayCollection包装器(\ Doctrine \ Common \ Collections \ ArrayCollection()),它与上面的实现几乎完全相同(您仍需要传递闭包)。

$myCollection->filter($closure);

答案 1 :(得分:0)

我遇到了类似的问题,我必须将实体集合与外部源同步。但是,我的问题不仅需要添加,还需要更新和删除。我使用代码将ArrayCollection与另一个数组区分开来,并根据差异调用CRUD方法。就我从文档中可以看出,学说本身并没有处理这个问题。平均性能应该是O(n)但需要一些记忆。

/**
 * @param array $source - the array we are starting with
 * @param array $new - the array we want to end with
 * @param $fnHash - function used to determine object equality, not based on object id
 * @param $fnUpdate - function to perform update of existing object, takes current object and new object as params
 * @param $fnAdd - function to perform insert
 * @param $fnDelete - function to perform delete
 */
public static function syncArrays(array $source, array $new,
        $fnHash, $fnUpdate, $fnAdd, $fnDelete)
{
    // make modifiable array copies mapped by hashes of the elements

    $sourceKeys = array_map($fnHash, $source);
    $hasKeys =count($sourceKeys) > 0;
    $newarray = ($hasKeys) ? array_combine(array_map($fnHash, $new), $new) : $new;
    if ($hasKeys) { // true => may have updates or deletes
        $sourcearray = array_combine($sourceKeys, $source);

        // updates
        foreach ($sourceKeys as $hashkey) {
            if (isset($sourcearray[$hashkey]) && isset($newarray[$hashkey])) {
                $fnUpdate($sourcearray[$hashkey], $newarray[$hashkey]);
                unset($sourcearray[$hashkey]);
                unset($newarray[$hashkey]);
            }
        }


        // deletes
        foreach ($sourcearray as $entity) {
            $fnDelete($entity);
        }
    }
    //adds
    foreach ($newarray as $entity) {
        $fnAdd($entity);
    }
}

我称之为更新我的学说关联$ parentEntity-> getPayments()的方式是:

ArrayHelper::syncArrays($parentEntity->getPayments()->toArray(), $newPayments,
    function($entity) {return $a->getName();}, // hash function
    function($current, $new) {
        $current->setTotal($new->getTotal()); // update function
    },
    function($a) use ($parent, $manager) {
        $parent->addVendorPaymentObject($a);  // add function
        $manager->persist($a);
    },
    function($a) use ($manager) {  // delete function
        $manager->remove($a);
    }
);