从实体中获取entitymanager

时间:2013-11-20 01:51:49

标签: symfony doctrine-orm

是的,我知道,我不应该这样做。但从开发人员的角度来看,在我的特定情况下,它“似乎”是最简单的解决方案(但我愿意接受更好的建议)。

我有3个实体:List,Item和Product。列表可以有多个项目,项目可以链接多个产品。

在Twig模板中,枚举列表的项目,并且对于每个项目,也枚举所有链接的产品。到目前为止,这一切都很简单。

现在我想通过添加推荐产品来扩展这一点,如果链接产品的数量小于3.这些建议没有链接到数据库中的项目,它是一个使用该名称的临时全文查询作为搜索值的项目,并返回匹配产品的列表。此搜索功能已在Product实体的Repository类中提供。

所以我想在Item实体中添加一个名为getSuggestions()的函数。然后,此函数将检索3个可与Item匹配的产品,而不实际将它们链接到该项目。因此,如果我在该函数中有EM,我可以通过将Item传递给它来简单地获取Products实体的Repository类来进行全文搜索。这样我就可以在模板中获取建议列表(我需要它们的唯一地方),只需在模板中处理Item对象时调用getSuggestions函数即可。

2 个答案:

答案 0 :(得分:2)

  

但我愿意接受更好的建议

我认为Single Responsibility Principle是停下来并重新考虑这一点的好理由。 Item应该做一件事。跟踪其属性和关系。它不应该是查询数据库。它不应该是计算事物(通常)。它应该是一种传递属性和关系的手段。

事实上,保持Entity的解耦是很好的,这样他们就不会意识到数据库甚至存在。保持可测试性是一个重要原因。但是,这意味着您有一天可以更改您的应用程序以获取来自其他来源的Entity数据,例如第三方API或其他内容,以及您的所有Entity和依赖的代码它们没有变化。

现在,我的建议是将这个逻辑转移到一个新类。我会把命名留给你,但这可能是一个名为Suggester的类。 Suggester有一个方法,它接受Item并使用EntityManager(通过依赖注入)来进行查询。

将此方法添加到自定义ProductRepository也可能是个好主意。该类负责查询Product的数据库,因此它是此代码的合理位置。正如您所说“我可以通过将Item传递给它来简单地获取Products实体的Repository类来执行全文搜索。”

你说你想要Item上的一个属性,所以它很容易在Twig中使用。你应该停下来重新考虑一下。您的Twig模板是您在MVC中的“视图”。该视图负责呈现数据。当您查询数据库时,您应该从您的模型执行此操作,该模型由您的控制器调用。我看到它的方式,您要么获得控制器中的建议并将它们传递到模板中,要么为模板提供能够执行查询的服务(沿着我的{上面{1}}。

答案 1 :(得分:0)

我会采取其他方式。

使用Doctrine事件监听器,在使用事件postLoad从DB加载初始数据后,您可以阻止链接产品的数量,如果低于3,则可以自动运行它。进入doctrine事件监听器,您可以轻松添加容器。

services:
my.listener:
    class: Acme\SomeBundle\Listener\YourListener
    arguments: [@container_or_entity_manager]
    tags:
        - { name: doctrine.event_listener, event: postLoad }