如何在symfony2中访问实体的存储库方法?

时间:2014-07-12 12:23:10

标签: symfony repository entity

我遇到问题请帮帮我。这是scenarario:

我有一个实体“User”和相应的存储库“UserRepository”,在我的实体里面只有getter和setter方法。我写给UserRepository的所有自定义查询。现在在我的UserController里面,我试图访问我无法访问的存储库方法。 例如 用户实体:

class User
{
    ...

    public function getId()
    {
        return $this->id;
    }

    public function setId($id)
    {
        return $this->id=$id;
    }
    public function setProperty($property)
    {
        $this->property = $property;
    }


    public function getProperty()
    {
        return $this->property;
    }

    ....

    }
  ?>

UserRepository:

class UserRepository extends EntityRepository
{


    public function findUsersListingById($id)
    {
        $queryBuilder = $this->getEntityManager()->createQueryBuilder();

       $query = $em->createQuery(
                    "SELECT U
                    FROM  UserEntityPathGoesHere
                    WHERE U.id IN (".implode(",", $id).")"
                );

        $users = $query->getResult();

        return $users;
    }

    public function sayHelloWorld(){

        echo ' Hello World';
    }

}
?>

UserController中

class UserController
{
 ...


$users=$this->getDoctrine()
        ->getRepository('MyUserEntityPath')
        ->findUsersListingById($ids);

    //now I have multiple users I want to iterate through each user for associating additional data with each user

     foreach($users as $user)
     {
        $temp = array();

        //I am able to access getId method which is  defined in User entity
        $temp['id'] = $user->getId();

        //however I am not able to  access method from UserRepository, I tried something like below which gives me error  call to undefined function sayHelloWorld
        $temp['status'] = $user->sayHelloWorld();

       ....

     }


}

...

如何访问实体的存储库方法?可能吗 ?如果没有,那么解决方案的替代方案是什么?

4 个答案:

答案 0 :(得分:21)

一切皆有可能但是由于关注点的分离,您不应该从实体本身访问实体的存储库。

请参阅此Stackoverflow answer for more details

基本上,整个想法是您希望以下列方式组织您的应用程序。

简而言之:

控制器> 存储库> 实体。

不应该向另一个方向走,否则会造成混乱。

如果您想进一步分离关注点,可以执行以下操作。

控制器> 服务> 存储库> 实体

替代解决方案:

  • 创建一个访问服务(访问存储库)或存储库的Twig extension
  • 在存储库中创建方法,在控制器中调用方法,将数据映射到ID(数组的键是ID),将数组传递给模板,然后使用实体ID从数组中提取数据< / LI>
  • 在您的存储库中创建一个方法,调用控制器中的方法,将数据注入您的实体并通过模板中的实体访问数据。

可能还有其他人,但您会更清楚地知道您的应用程序是如何组织的。

答案 1 :(得分:1)

您需要为您的用户实体声明UserRepositoryEntityRepository。在User实体中添加此注释:

/**
 * @ORM\Entity(repositoryClass="Acme\StoreBundle\Entity\UserRepository")
 */

有关更详细的说明,请参阅the docs

答案 2 :(得分:1)

如果捆绑包是Acme / DemoBundle,则可以预期

用户实体

namespace Acme/DemoBundle/Entity

use Doctrine\ORM\Mapping as ORM;


/**
 *
 * @ORM\Table(name="user")
 * @ORM\Entity(repositoryClass="Acme/DemoBundle/Entity/UserRepository")
 */
class User 
{
...
}

用户存储库

namespace Acme/DemoBundle/Entity

use Doctrine\ORM\Mapping as ORM;

class UserRepository extends EntityRepository
{
...
}   

对于一组id,也可以在控制器中执行以下操作:

...
$em = $this->getDoctrine()->getManager();
$users = $em->getRepository("AcmeDemoBundle:User")->findAllById($idArray);
...

要在控制器中迭代用户,可以使用foreach循环,如下所示:

foreach ($users as $user) {
//each user is an array
...
$id = $user['id'];
...
}

或在模板中:

{% for user in users %}
...
{{ user.firstName }}
...
{% endfor %}

答案 3 :(得分:0)

您可以使用doctrine中的postLoad事件,并将您想要的所有内容注入实体。事件监听器如下所示:

    <?php
namespace AppBundle\EventListener;


use AppBundle\Entity\MyEntity;
use Doctrine\ORM\Event\LifecycleEventArgs;

/**
 * Class MyEntityListener
 */
class MyEntityListener
{

    public function postLoad(LifecycleEventArgs $eventArgs)
    {
        /** @var MyEntity $document */
        $document = $eventArgs->getEntity();
        if(!($document instanceof MyEntity)){
            return;
        }
        $document->setEntityManager($eventArgs->getEntityManager());

    }
}

和service.yml:

services:
app.myentity.listener:
  class: AppBundle\EventListener\MyEntityListener
  tags:
    - { name: doctrine.event_listener, event: postLoad }

您的实体需要方法setEntityManager并准备好。

相关问题