Symfony2-访问实体中的存储库功能
假设我的数据库中有两个表:兔子和胡萝卜。 兔子可以有0个或多个胡萝卜,一个胡萝卜属于一只兔子。这是两个表之间的1,n关系 我有两个实体,兔子和胡萝卜 我在模板中传递了一个兔子数组,我想从每只兔子那里获得特定的胡萝卜并显示它们:假设我想从数组中的每只$rabbit中获得10个更昂贵的胡萝卜(胡萝卜价格将存储在胡萝卜表中) 比如:Symfony2-访问实体中的存储库功能,symfony,entity,Symfony,Entity,假设我的数据库中有两个表:兔子和胡萝卜。 兔子可以有0个或多个胡萝卜,一个胡萝卜属于一只兔子。这是两个表之间的1,n关系 我有两个实体,兔子和胡萝卜 我在模板中传递了一个兔子数组,我想从每只兔子那里获得特定的胡萝卜并显示它们:假设我想从数组中的每只$rabbit中获得10个更昂贵的胡萝卜(胡萝卜价格将存储在胡萝卜表中) 比如: {% for rabbit in rabbits %} {% for carrot in rabbit.getMoreExpensiveCarrots %}
{% for rabbit in rabbits %}
{% for carrot in rabbit.getMoreExpensiveCarrots %}
{{ carrot.price }}
{% endfor %}
{% endfor %}
我使用的是repository类,但如果我在rabbit repository类中创建函数getMoreExpensiveCarrots($rabbit),我将无法从这样的实体类访问该函数,这正是我想要的:
$rabbit->getMoreExpensiveCarrots()
我认为这样做的一种方法是在rabbit实体中创建一个getMoreExpensiveCarrots():
// Entity rabbit
class Rabbit
{
public function getMoreExpensiveCarrots()
{
// Access repository functions like getMoreExpensiveCarrots( $rabbit )
// But how can I do such thing ? Isn't that bad practise ?
return $carrots;
}
}
我想我也能做到:
// Entity rabbit
class Rabbit
{
public function getMoreExpensiveCarrots()
{
$this->getCarrots();
// Then try here to sort the carrots by their price, using php
return $carrots;
}
}
这是我的控制器:
public function indexAction()
{
$em = $this->getDoctrine()->getEntityManager();
$rabbits = $em->getRepository('AppNameBundle:Rabbit')->getSomeRabbits();
return $this->render('AppNameBundle:Home:index.html.twig',
array(
"rabbits"=>$rabbits
));
}
从模板中的每个兔子调用getMoreExpensiveCarrots函数的最佳实践是什么
谢谢 您的实体类应该只关心它们所表示的对象,而完全不了解实体管理器或存储库 这里一个可能的解决方案是使用包含
getMoreExpensiveCarrots
方法的服务对象(RabbitService
)。允许服务了解实体管理器和存储库,因此您可以在这里执行任何复杂的操作
通过使用服务对象,您可以保持关注点的分离,并确保您的实体类完成了它们想要完成的任务,仅此而已
您还可以使用第二个选项,假设胡萝卜存储在ArrayCollection中。您只需在方法中执行所需的任何排序逻辑。这很好,因为您将对实体可用的数据进行操作。让我来解释一下。原则2 ORM确实需要重新思考。你现在的心态是,兔子应该能够在需要胡萝卜的时候查询胡萝卜。你需要改变这种心态 对于教义2,想法是在你创造兔子的时候就给兔子胡萝卜。换句话说,它是在查询时完成的。假设无论查询数据库中兔子的过程是什么,都知道您还需要一组特定的胡萝卜 在这种情况下,您需要10个最昂贵的胡萝卜,因此您的流程需要知道这一点。现在回到@Arms answer,使用名为loadRabbitsWithExpensiveCarrots的方法创建一个RabbitManager服务。返回值将是一个兔子数组,其中已经填充了胡萝卜 更新此内容以处理评论
希望这有帮助。可能只是让你更加困惑。回到基本面。忘掉存储库和服务,只关注兔子和胡萝卜
class Rabbit
{
/** @ORM\OneToMany(targetEntity="Carrot", mappedBy="rabbit" */
protected $carrots;
public function getCarrots() { return $this->carrots; }
public function getMoreExpensiveCarrots()
{
// Get all carrots
$carrots = $this->getCarrots()->toArray();
// Sort by price
// http://php.net/manual/en/function.usort.php
usort(&$carrots,array($this,'compareTwoCarrotsByPrice'));
// Now slice off the top 10 carrots (slice - carrots, hah, kindo of funny
$carrots = array_slice($carrots, 0, 10);
// And return the sorted carrots
return $carrots;
}
public function compareTwoCarrotsByPrice($carrot1,$carrot2)
{
if ($carrot1->getPrice() > $carrot2->getPrice()) return -1;
if ($carrot1->getPrice() < $carrot2->getPrice()) return 1;
return 0;
}
}
这里唯一的缺点是,对于每只兔子,条令会自动生成一个针对所有胡萝卜的单独查询。在某一点上,性能将受到阻碍。当您达到这一点时,您可以返回到原始查询,并查看如何更有效地引入胡萝卜。但是首先让上面的类工作,因为我认为这可能是您的阻塞点。然后我将从我的实体兔子调用该服务?您将单独调用该服务,就像从控制器调用一样。对不起,我是一个初学者,在这种情况下,我不太理解存储库和服务之间的区别,因为我必须从控制器调用它:(我不想从我的控制器调用getMoreExpensiveCarrots,而是从我模板中的每个$rabbit。实际上,在我的控制器中,我就是这样做的:Rabbts=$em->getRepository('AppNameBundle:Rabbit')->getSomeRabbits();现在我应该如何调用该服务的getMoreExpensiveCarrots?不是。有人能告诉我应该如何使用该服务吗?我如何从$rabbits调用我的getMoreExpensiveCarrots?好的,谢谢你的帮助,我现在更了解它是如何工作的了。
{% for rabbit in rabbits %}
{% for carrot in rabbit.getMoreExpensiveCarrots %}
{{ carrot.price }}
{% endfor %}
{% endfor %}