Как обновить запись отношениями OneToMany в Doctrine 2? - PullRequest
1 голос
/ 24 июня 2011

У меня есть пользовательский объект, и я пытаюсь обновить его с помощью UserService.Проблема возникает, когда я пытаюсь обновить свойство, заданное в качестве коллекции массивов.

/**
 * 
 * @param \Doctring\Common\Collections\Collection $property
 * @OneToMany(targetEntity="Countries",mappedBy="user", cascade={"persist", "remove"})
 */
private $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 ... помогите мне разобратьсяиз этого.

Ответы [ 2 ]

0 голосов
/ 17 июня 2014

Для моего текущего и личного выбора я использую DQL, чтобы УДАЛИТЬ все должные боковые строки для сопоставленной сущности, а затем вставляю новую.

class Rule
{

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

Поэтому, когда я передаю новый уровень в моем вызове, яЯ просто удаляю все Уровни для этой Роли из Mapper Rule

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();

Надежда, которая помогает

0 голосов
/ 24 июня 2011

Это на самом деле зависит от вашего варианта использования.

Как вы сказали, вы можете либо удалить все страны, прежде чем устанавливать новые, либо вычислить дельту и обновить только нужные.

  • В каких странах вы предоставляете свои услуги?Дельта?Или полный список?
  • Есть ли у вас ограничения производительности?Если да, какова стоимость операторов DELETE по сравнению с SELECT, а затем UPDATE?

Вычислить дельту, тогда UPDATE может быть сложным и сложным, в большинстве случаев вам лучше просто удалить все и вставить.

...