我遇到问题请帮帮我。这是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();
....
}
}
...
如何访问实体的存储库方法?可能吗 ?如果没有,那么解决方案的替代方案是什么?
答案 0 :(得分:21)
一切皆有可能但是由于关注点的分离,您不应该从实体本身访问实体的存储库。
请参阅此Stackoverflow answer for more details。
基本上,整个想法是您希望以下列方式组织您的应用程序。
简而言之:
不应该向另一个方向走,否则会造成混乱。
如果您想进一步分离关注点,可以执行以下操作。
替代解决方案:
可能还有其他人,但您会更清楚地知道您的应用程序是如何组织的。
答案 1 :(得分:1)
您需要为您的用户实体声明UserRepository
为EntityRepository
。在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并准备好。