如何使用Doctrine 2中的OneToMany关系更新记录?

问题描述 投票:0回答:2

我有一个用户实体,我正在尝试从 UserService 更新它。当我尝试更新设置为数组集合的属性时,问题就出现了。

/**
 * 
 * @param \Doctring\Common\Collections\Collection $property
 * @OneToMany(targetEntity="Countries",mappedBy="user", cascade={"persist", "remove"})
 */
private $countries;

我不确定在设置它们之前是否应该以某种方式删除所有 $countries,或者是否有办法选择要删除的国家并设置不同的国家......这就是我的 updateUser 方法到目前为止看起来:

public function updateUser($user) {
    $entity = $this->getUser($user['id']);
    if (!$entity)
        throw new Exception('Error saving user!');
    $countries = $this->getCountriesArray($user); //countries already set in the db
    $tempCountries = array();
    $delete = array();
    foreach ($countries as $country) {
        $found = false;
        if (in_array($country, $user['countries'])) {
            $tempCountries[] = $country;
        } else {
            $delete[] = $country;
        }
    }
    $tempCountries = array_unique(array_merge(                //combine the countries from the db we want to leave 
                                        $tempCountries,       //with those the user selected
                                        $user['countries']));
    ...
    //here I need something to remove the countries in $delete...right?
    ...
    $entity->setEmail($user['email']);
    $entity->setResponsable($user['responsable']);
    $entity->setPassword($this->createPass($user['password']));
    $entity->setUrl($user['url']);
    $entity->setRole($user['role']);

    $modelCountries = array();
    foreach($tempCountries as $c) {
        $p = new Countries();
        $p->setCountryName($c);
        $p->setUser($entity);
        $modelCountries[] = $p;
    }
    $entity->setCountries($modelCountries);

    $this->em->persist($entity);
    $this->em->flush();
}

请 stackOverflow...帮助我理解这一点。

php doctrine-orm doctrine one-to-many
2个回答
0
投票

这实际上取决于您的用例。

正如您所说,您可以删除之前的所有国家/地区以设置新国家/地区,也可以计算增量并仅更新所需的国家/地区。

  • 你们向哪些国家/地区提供服务?三角洲?或者完整列表?
  • 您有性能限制吗?如果是,那么 DELETE 语句与 SELECT 然后 UPDATE 的成本是多少?

计算增量,然后更新可能会很棘手且困难,在大多数情况下,您最好只想删除所有内容并插入。


0
投票

对于我当前和个人的选择,我使用 DQL 删除映射实体的所有欠边行,然后插入新行。

class Rule
{

/**
 * @OneToMany(targetEntity="Tier", mappedBy="rule", cascade={"persist", "remove"})
 * @JoinColumn(name="ruleId", referencedColumnName="ruleId")
 * @var Tier[]
 */
public $tiers;

因此,当我在通话中传递新层时,我只需从规则映射器中删除该角色的所有层

public function resetTiers($ruleId)
{
    $modelClass = "Tier";

    $q = $this->doctrineEntityManager->createQuery("Delete from $modelClass m where m.rule =" . $ruleId);
    $numDeleted = $q->execute();

    return $numDeleted;
}

然后调用通常的


     $this->doctrineEntityManager->persist($rule);
     $this->doctrineEntityManager->flush();

希望有帮助

© www.soinside.com 2019 - 2024. All rights reserved.