Доктрина: Как сохранить только элементы коллекции, которые еще не существуют в БД - PullRequest
1 голос
/ 19 января 2010

У меня есть коллекция элементов для сохранения в базе данных, но я хочу, чтобы запись была вставлена, только если она не существует.

Я думаю, что наиболее эффективным способом было бы отфильтровать коллекцию перед сохранением. Может ли Doctrine сделать это автоматически?

Или я должен получить все идентификаторы всех элементов в коллекции, затем запросить в базе данных элементы, которых нет в списке этих идентификаторов, затем в foreach удалить все ненужные элементы коллекции и, наконец, сохранить коллекцию

Какой лучший подход предложил?

Ответы [ 2 ]

2 голосов
/ 11 февраля 2010

Это функция сохранения из класса Doctrine_Collection

 public function save(Doctrine_Connection $conn = null, $processDiff = true)
    {
        if ($conn == null) {
            $conn = $this->_table->getConnection();
        }

        try {
            $conn->beginInternalTransaction();

            $conn->transaction->addCollection($this);

            if ($processDiff) {
                $this->processDiff();
            }

            foreach ($this->getData() as $key => $record) {
                $record->save($conn);
            }

            $conn->commit();
        } catch (Exception $e) {
            $conn->rollback();
            throw $e;
        }

        return $this;
    }

Я не уверен, откуда вы берете свою коллекцию или собираете ее вручную, но вы можете попытаться расширить класс Doctrine_Collection и перегрузить функцию сохранения, как эта

<?php

class My_Collection extends Doctrine Collection
{

  public function save(Doctrine_Connection $conn = null, $processDiff = true, $createOnly = true)
    {
        if ($conn == null) {
            $conn = $this->_table->getConnection();
        }

        try {
            $conn->beginInternalTransaction();

            $conn->transaction->addCollection($this);

            if ($processDiff) {
                $this->processDiff();
            }

            foreach ($this->getData() as $key => $record) {

                if($createOnly)
                {
                    if ($record->exists())
                    {
                        $record->save($conn);
                    }
                }else{
                    $record->save($conn);
                }
            }

            $conn->commit();
        } catch (Exception $e) {
            $conn->rollback();
            throw $e;
        }

        return $this;
    }

}
0 голосов
/ 29 января 2010

Я ничего не знаю о Doctrine, но запрос MySQL REPLACE делает то, что вам нужно - обновляет существующие строки и создает новые строки, если не найдено совпадений первичного ключа.

...