2012-07-10 7 views

Antwort

13

Es ist möglich, so viele Repositories zu haben, wie Sie möchten. Es kann jedoch nur ein einzelnes Repository mit dem Entity Manager verknüpft werden.

Sie müssen einige Dienste definieren, um ein benutzerdefiniertes Repository hinzuzufügen.

<!-- My custom repository --> 
<service id="acme.repository.my_entity" class="Acme\FQCN\MyEntityRepository" > 
    <argument type="service" id="doctrine.orm.entity_manager" /> 
    <argument type="service" id="acme.metadata.my_entity" /> 
</service> 

<!-- MyEntity metadata --> 
<service id="acme.metadata.my_entity" class="Doctrine\ORM\Mapping\ClassMetaData"> 
    <argument>Acme\FQCN\MyEntity</argument> 
</service> 

Die Repository-Klasse würde von EntityRepository erben hat.

namespace Acme\FQCN; 

use Doctrine\ORM\EntityRepository; 

class MyEntityRepository extends EntityRepository 
{ 
    /** 
    * If you want to inject any custom dependencies, you'd have either have to 
    * add them to the construct or create setters. I'd suggest using setters 
    * in which case you wouldn't need to use the constructor in this class. 
    * 
    * public function __construct($em, Doctrine\ORM\Mapping\ClassMetadata $class, $custom_dependency) 
    * { 
    *  parent::__construct($em, $class); 
    * } 
    * 
    */ 
} 

Leider können Sie es nicht über den Doktrin-Dienst abrufen. Stattdessen rufen Sie sie direkt aus dem Behälter:

$this->get('acme.repository.my_entity'); 

EDIT

Wenn Sie ein Repository erstellen, von nicht an Einheiten verknüpft werden sollten, einfach einen Dienst erstellen und die injizieren notwendige Abhängigkeiten.

<!-- Repository for misc queries --> 
<service id="acme.repository.misc" class="Acme\FQCN\MiscRepsitory"> 
    <argument type="service" id="database_connection" /> 
</service> 

Da Sie nicht in einem benutzerdefinierten Repository jede der Lehre ORM-Funktionen verwenden, gibt es keine Notwendigkeit EntityManager zu verlängern.

namespace Acme\FQCN; 

use \Doctrine\DBAL\Connection; 

class MiscRepository 
{ 
    protected $conn; 

    public function __construct(Connection $conn) 
    { 
     $this->conn = $conn; 
    } 
} 
+0

Sorry, ich meinte, dass Repository sollte nicht mit einer Entität verbunden werden. Also, warum die Metadaten-Sache? – gremo

+0

@Gremo in diesem Fall wäre es sinnvoll, nur einen zusätzlichen Dienst zu erstellen und eine Datenbankverbindung selbst zu injizieren. – gilden

+0

nach dem Injizieren von Datenbankverbindung sollte ich nur eine Klasse machen, die von EntityRepository erbt, bin ich richtig? – gremo

1

Mein Vorschlag ist, eine einfache PHP-Klasse mit den erforderlichen Abhängigkeiten im Konstruktor zu erstellen und durch den Service-Container zu bekommen.

4

Ich nahm eine etwas andere Lösung mit Symfony2 Parent Services.

Zunächst einmal habe ich einen Eltern-Service erstellt, eine GenericRepository Klasse, die ein paar Methoden aufzeigt und das Leben einfacher macht, falls wir unseren Code in Zukunft neu gestalten wollen.

services.yml

acme_core.generic_repository: 
    abstract: true 
    class: Acme\Bundle\CoreBundle\Repository\GenericRepository 
    arguments: [@doctrine.orm.entity_manager] 

Acme\Bundle\CoreBundle\Repository\GenericRepository

<?php 

namespace Acme\Bundle\CoreBundle\Repository; 

use Doctrine\ORM\EntityManager; 

/** 
* Class GenericRepository 
* @package Acme\Bundle\CoreBundle\Repository 
*/ 
abstract class GenericRepository { 
    /** 
    * @var EntityManager 
    */ 
    private $entityManager; 

    /** 
    * @param EntityManager $entityManager 
    */ 
    public function __construct(EntityManager $entityManager) { 
     $this->entityManager = $entityManager; 
    } 

    /** 
    * @return EntityManager 
    */ 
    public function getEntityManager() { 
     return $this->entityManager; 
    } 

    /** 
    * @return \Doctrine\DBAL\Connection 
    */ 
    public function getConnection() { 
     return $this->getEntityManager()->getConnection(); 
    } 

    /** 
    * @return string 
    */ 
    abstract function getTable(); 
} 

Jetzt wollen wir ein neues Repository definieren:

services.yml

# Repositories 
acme_product.repository.product_batch: 
    parent: acme_core.generic_repository 
    class: Acme\Bundle\ProductBundle\Repository\ProductBatchRepository 

Acme\Bundle\ProductBundle\Repository\ProductBatchRepository

<?php 

namespace Acme\Bundle\ProductBundle\Repository; 

use Acme\Bundle\CoreBundle\Repository\GenericRepository; 

/** 
* Class ProductBatchRepository 
* @package Acme\Bundle\ProductBundle\Repository 
*/ 
class ProductBatchRepository extends GenericRepository { 
    /** 
    * @param int $batchId 
    * @return integer The number of affected rows. 
    */ 
    public function deleteBatch($batchId) { 
     $table = $this->getTable(); 

     return $this->getConnection()->delete($table, [ 
      'id' => $batchId 
     ]); 
    } 

    /** 
    * {@inheritdoc} 
    */ 
    public function getTable() { 
     return 'product_batch'; 
    } 
} 

Die deleteBatch() Methode erstellt und führt die folgende Abfrage:

DELETE FROM product_batch WHERE id = ?

schließlich in unserem Controller:

public function deleteAction() { 
    $batchId = $this->getRequest()->get('batchId'); 

    $affectedRows = $this->get('acme_product.repository.product_batch')->deleteBatch($batchId); 

    return $this->render(/**/); 
} 

Für weitere Informationen und EntityManager/Verbindung Verwendung finden Sie in der offiziellen Dokumentation: http://doctrine-orm.readthedocs.org/en/latest/reference/native-sql.html

Verwandte Themen