2

propel には findOneOrCreate()があります

例。

$bookTag = BookTagQuery::create()
->filterByBook($book)
->findOneOrCreate();   

ドクトリンでは、コントローラーのどこでもそのようなことができます。

...................
       $filename='something';
       $document_exists = $em->getRepository('DemoBundle:Document')
                ->findOneBy(array('filename' => $filename));

        if (null === $document_exists) {
            $document = new Document();
            $document->setFilename($filename);
            $em->persist($document);
            $em->flush();
        }    

Doctrineでこれを達成する別の方法はありますか?

エンティティ リポジトリ内でエンティティ マネージャを呼び出しても問題ありませんか? 助言がありますか?

4

2 に答える 2

4

最も簡単な方法は、ベース リポジトリを拡張することです。

// src/Acme/YourBundle/Entity/YourRepository.php
namespace Acme\YourBundle\Entity;

use Doctrine\ORM\EntityRepository;

class YourRepository extends EntityRepository
{
    public function findOneOrCreate(array $criteria)
    {
        $entity = $this->findOneBy($criteria);

        if (null === $entity)
        {
           $entity = new $this->getClassName();
           $entity->setTheDataSomehow($criteria); 
           $this->_em->persist($entity);
           $this->_em->flush();
        }

        return $entity
    }
}

次に、エンティティにこのリポジトリを使用するか、特定のエンティティに対してさらに拡張するように指示します。

// src/Acme/StoreBundle/Entity/Product.php
namespace Acme\StoreBundle\Entity;

use Doctrine\ORM\Mapping as ORM;

/**
 * @ORM\Entity(repositoryClass="Acme\YourBundle\Entity\YourRepository")
 */
class Product
{
    //...
}

コントローラーで使用します。

$em = $this->getDoctrine()->getManager();
$product = $em->getRepository('AcmeStoreBundle:Product')
              ->findOrCreate(array('foo' => 'Bar'));

ソース: http://symfony.com/doc/current/book/doctrine.html#custom-repository-classes

flushこのように EntityManager で保存されていないすべての変更をフラッシュするため、リポジトリ内に注意してください。

于 2013-07-30T07:43:27.717 に答える