在 Doctrine 2.0 实体中使用 EntityManager

发布于 2024-09-30 11:53:38 字数 737 浏览 4 评论 0原文

我有 2 个实体:国家/地区(id、名称)和映射(id、对象、internalId、externalId)。 国家和映射不通过关联连接(因为映射不仅具有国家/地区的行)。我需要使用以下条件获取国家/地区的外部ID:

  • country.id = mapping.internalId
  • mapping.object = 'country'

所以我计划在中添加函数 getExternalId()国家/地区

function getExternalId() {
    $em = Registry::getEntityManager();

    $mapping = $em->getRepository('Mapping')->findOneBy(array(
        'object'     => 'country',
        'internalId' => $this->getId()
    ));

    return !empty($mapping) ? $mapping->getExternalId() : false;
}

问题:

  1. 在实体内部使用 EntityManager 是一种好的做法吗?如果不是,请解释一下在我的情况下如何获取外部 ID?
  2. 也许可以使用 yaml 文件关联国家/地区和地图?

提前致谢!

I have 2 entities: Country (id, name) and Mapping (id, object, internalId, externalId).
Country and Mapping are not connected with associations (because Mapping has rows not only for country). I need to get external id for country using following conditions:

  • country.id = mapping.internalId
  • mapping.object = 'country'

So I plan to add function getExternalId() in Country

function getExternalId() {
    $em = Registry::getEntityManager();

    $mapping = $em->getRepository('Mapping')->findOneBy(array(
        'object'     => 'country',
        'internalId' => $this->getId()
    ));

    return !empty($mapping) ? $mapping->getExternalId() : false;
}

Questions:

  1. Is it good practice to use EntityManager inside entities? If no, please explain how to get external id in my case?
  2. Maybe it is possible to associate Country and Mapping using yaml files?

Thanks in advance!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

错爱 2024-10-07 11:53:38

允许实体对象依赖实体管理器并不是一个好主意。它将实体与持久层联系起来,这是 Doctrine 2 专门试图解决的问题。依赖实体管理器的最大麻烦是它使您的模型难以脱离数据库进行隔离测试。

您可能应该依赖服务对象来处理依赖于实体管理器的操作。

// CountryService
public function getExternalId($country) {}

此外,您可以在模型上创建代理方法来调用外部设置的服务对象。在测试时,服务对象比实体管理器更容易模拟。

$country->setService($countryService);
$country->getExternalId();

// Country
public function getExternalId()
{
   $this->_service->getExternalId($this);
}  

It is not a good idea to allow an entity object to rely on the entity manager. It ties the entity to the persistence layer, which was a problem Doctrine 2 was specifically trying to solve. The biggest hassle in relying on the entity manager is that it makes your model hard to test in isolation, away from the database.

You should probably be relying on service objects to handle the operations that rely on the entity manager.

// CountryService
public function getExternalId($country) {}

Additionally, you could create proxy methods on your model to call out to a service object that is set externally. A service object would be much easier to mock while testing than the entity manager would be.

$country->setService($countryService);
$country->getExternalId();

// Country
public function getExternalId()
{
   $this->_service->getExternalId($this);
}  
属性 2024-10-07 11:53:38

这可能不是最好的主意,但有一个简单的方法可以做到这一点。

学说中的 UnitOfWork 类会将任何实现 ObjectManagerAware 的实体与该实体的实体管理器和类元数据结合在一起。

要在实体中获取实体管理器,您所要做的就是实现接口,如下例所示:

use Doctrine\Common\Persistence\Mapping\ClassMetadata;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\ObjectManagerAware;

/**
 * @ORM\Entity
 */
class MyEntity implements ObjectManagerAware
{
    public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata)
    {
        $this->em = $objectManager;
    }
}

如果您创建一个新实体而不是从数据库查询它,则需要手动设置实体管理器,例如使用 setter 方法。

This might not be the best idea, but there is a simple way to do this.

The UnitOfWork class in doctrine will hydrate any entity which implements ObjectManagerAware with the entity manager and class metadata for that entity.

All you have to do to get the entity manger in your entity is implement the interface as shown in the example below:

use Doctrine\Common\Persistence\Mapping\ClassMetadata;
use Doctrine\Common\Persistence\ObjectManager;
use Doctrine\Common\Persistence\ObjectManagerAware;

/**
 * @ORM\Entity
 */
class MyEntity implements ObjectManagerAware
{
    public function injectObjectManager(ObjectManager $objectManager, ClassMetadata $classMetadata)
    {
        $this->em = $objectManager;
    }
}

If you create a new entity rather than querying it from the database, you will need to set the entity manager manually, for example with a setter method.

幻想少年梦 2024-10-07 11:53:38

我认为您需要使用的是实体存储库。这些在文档中都有详细介绍,尽管很难找到相关信息。这是 入门一文,记录了如何为您的实体创建“访问”功能的“存储库”。

此外,这里还有一些伪代码可以帮助您入门:

<?php
// repositories/CountryRepository.php

use Doctrine\ORM\EntityRepository;

class CountryRepository extends EntityRepository
{
    public function getExternalId()
    {

I think what you need to be using are Entity Repositories. These are detailed in the documentation, albeit a bit hard to find information on. Here is a link to the Getting Started article which documents how one would create a "repository" of 'access' functions for your entities.

Additionally here is some pseudo-code to get you started:

<?php
// repositories/CountryRepository.php

use Doctrine\ORM\EntityRepository;

class CountryRepository extends EntityRepository
{
    public function getExternalId()
    {
眸中客 2024-10-07 11:53:38

一个稍微前沿的附录(PHP 5.4 在本文发布时处于 alpha 2 版本),将来可能会用到:

这里是在 Doctrine2 中使用 php 5.4 特性的一些示例;其中之一称为活动实体,并在 Doctrine 2 中提供活动记录样式功能,包括从实体内部访问实体管理器。

A slightly cutting edge addendum to this (PHP 5.4 being at alpha 2 at time of this post) which may be of use in the future:

Here are some examples of using php 5.4 traits within Doctrine2; one of which is called active entity and provides active record style functionality within Doctrine 2 including access to the entity manager from within the entity.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文