2012-07-10 22 views

Respuesta

13

Es posible tener tantos repositorios como desee. Sin embargo, solo un repositorio único puede vincularse con el administrador de la entidad.

Debe definir algunos servicios para agregar un repositorio personalizado.

<!-- 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> 

La clase repositorio tendría que heredar de EntityRepository.

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); 
    * } 
    * 
    */ 
} 

Desafortunadamente no podrá recuperarlo a través del servicio doctrine. En su lugar, recuperar directamente desde el envase:

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

EDITAR

Si va a crear un repositorio que no debe estar vinculada a ninguna entidad, basta con crear un servicio de e inyectar el dependencias necesarias.

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

Puesto que usted no está utilizando cualquiera de las funciones de ORM de la doctrina en un repositorio personalizado, no hay necesidad de extender EntityManager.

namespace Acme\FQCN; 

use \Doctrine\DBAL\Connection; 

class MiscRepository 
{ 
    protected $conn; 

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

Lo siento, quería decir que el repositorio no debe asociarse con ninguna entidad. Entonces, ¿por qué los metadatos? – gremo

+0

@Gremo en ese caso, tendría sentido crear un servicio adicional e inyectar una conexión de base de datos. – gilden

+0

después de inyectar database_connection solo debería hacer una clase que herede de EntityRepository, ¿estoy en lo cierto? – gremo

1

Mi sugerencia es crear una clase PHP simple con las dependencias necesarias en el constructor y obtenerla a través del contenedor de servicios.

4

Adopté una solución ligeramente diferente utilizando los servicios para padres Symfony2.

Antes que nada, creé un servicio para padres, una clase GenericRepository que expone un par de métodos y hace la vida más fácil en caso de que deseemos refactorizar nuestro código en el futuro.

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

Ahora queremos definir un nuevo repositorio:

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'; 
    } 
} 

El método deleteBatch() crea y ejecuta la siguiente consulta:

DELETE FROM product_batch WHERE id = ?

Finalmente en nuestro controlador:

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

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

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

Para más información y gestor de la entidad/conexión uso, consulte la documentación oficial: http://doctrine-orm.readthedocs.org/en/latest/reference/native-sql.html

Cuestiones relacionadas