如何访问symfony 2中实体的存储库方法?

zzzyeukh  于 2023-10-24  发布在  其他
关注(0)|答案(4)|浏览(107)

我被一个问题卡住了,请帮助我。下面是场景:
我有一个实体“User”和对应的仓库“UserRepository”,在我的实体中只有getter和setter方法。所有的自定义查询我都写在UserRepository中。现在在我的UserController中,我试图访问我无法访问的仓库方法。例如,User实体:

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

    ....

    }
  ?>

用户存储库:

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

}
?>

用户控制器

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

       ....

     }

}

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

waxmsbnn

waxmsbnn1#

一切皆有可能然而由于关注点的分离,您不应该从实体本身访问实体的存储库。
看看这个Stackoverflow answer for more details
基本上,整个想法是,你想让你的应用程序组织如下。
简而言之:

Controller**>Repository>**Entities。

它不应该走另一个方向,否则会造成混乱。
如果你想更深入地了解关注点的分离,你可以做下面的事情。

Controller**>Service>Repository>**Entities

替代解决方案:

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

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

new9mtju

new9mtju2#

您可以使用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 }

你的Entity需要方法setbacktypeManager,你已经准备好了。

a14dhokn

a14dhokn3#

如果bundle是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 %}
jobtbby3

jobtbby34#

您需要将UserRepository声明为用户实体的EntityRepository。在User实体中添加以下注解:

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

更详细的描述请参见文档。

相关问题