【问题标题】:Doctrine mapping type entity to id, id to entityDoctrine 映射类型实体到 id,id 到实体
【发布时间】:2020-01-27 17:29:46
【问题描述】:

正如我在标题中所说,我想将一个对象转换为一个 ID(int/string)并从 ID 反向转换为一个对象。通常我会处理实体关系,但在这种情况下,我不知道其他实体/捆绑包,它应该独立工作。

我想,我可以为此使用原则映射类型,但是如何注入我的自定义实体加载器?所以也许我可以使用回调来获取数据。

这就是我的想法(伪代码):

class User {
    public function getId() { return 'IAmUserBobAndThisIdMyId'; }
}

class Meta {
    private $user;  // <== HERE I NEED THE MAGIC
    public function setUser($user) { $this->user = user; }
}

$user = new User();
$meta = new Meta();
$meta->setUser($user);
$em->persist($meta);  // <== HERE THE MAPPING TYPE SHOULD CONVERT THE ENTITY

知道我希望我的数据库中的实体是这样的:user:IAmUserBobAndThisIdMyId

反过来:

$meta = $repository->findOneById(1);  // HERE I NEED THE MAGIC AGAIN
$user = $meta->getUser();
echo $user->getId();

// output: IAmUserBobAndThisIdMyId

到目前为止,一切都很简单……但现在我需要一些逻辑和数据库访问来恢复该实体。加载很简单,但是如何将它注入到我的映射类型类中

我阅读了doctrine documentation,我想知道是否可以使用通过参数从AbstractPlatform $platform 获得的事件管理器。或者有没有更好的方法?

【问题讨论】:

  • 对不起,但不清楚你要完成什么你不能完成的事情。在您的“伪代码”中,您将User 实例传递给$meta。有什么问题?
  • 您是否阅读了我下面的问题?我需要将数据库值user:IAmUserBobAndThisIdMyId 转换为实体的“魔法”,我正在寻找一种将这种“魔法”注入我的映射类型对象的好方法。
  • 是的,我读过。我问是因为不清楚,不是因为我没有读过。目前还不清楚。我建议编辑您的代码,以便清楚您想要发生的事情,因为到目前为止它并不明显。祝你好运。
  • 谢谢!我已经编辑了我的问题。我认为这并不难,但我想避免丑陋的黑客攻击。

标签: symfony orm doctrine-orm doctrine mapping


【解决方案1】:

您可以尝试类似的方法,但我没有对此进行测试。您还可以使用教义 postLoad 和 postPersist/postUpdate 事件将您的用户实体转换为整数并返回。

doctrine.yaml

doctrine:
    dbal:
        ...
        types:
            user: App\Doctrine\DBAL\Type\UserType
        ...

用户类型.php

<?php

namespace App\Doctrine\DBAL\Type;

use Doctrine\DBAL\Platforms\AbstractPlatform;
use Doctrine\DBAL\Types\IntegerType;
use App\Repository\UserRepository;
use App\Entity\User;

class UserType extends IntegerType
{
    const NAME = 'user';

    private $userRepository;

    public function __construct(UserRepository $userRepository)
    {
       $this->userRepository = $userRepository;
    }

    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        return $this->userRepository->find($value);
    }

    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        if (!$value instanceof User) {
            throw new \InvalidArgumentException("Invalid value");
        }

        return $value->getId();
    }

    public function getName()
    {
        return self::NAME;
    }
}

【讨论】:

  • 这是我的第一个想法,但是基类的构造函数是“final”的。所以我不能将它用于依赖注入。我会尝试 DI over setter。谢谢!
【解决方案2】:

我找到了一个合适的解决方案,无需破解任何类来注入一些服务。类型映射类触发一个事件并在外部处理转换。

class EntityString extends Type
{
    // ...

    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        return $this->dispatchConverterCall($platform, TypeMapperEventArgs::TO_PHP_VALUE, $value);
    }

    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        return $this->dispatchConverterCall($platform, TypeMapperEventArgs::TO_DB_VALUE, $value);
    }

    protected function dispatchConverterCall(AbstractPlatform $platform, $name, $value)
    {
        $event = new TypeMapperEventArgs($name, $value);
        $platform->getEventManager()->dispatchEvent(TypeMapperEventArgs::NAME, $event);

        return $event->getResult();
    }

    // ...
}

可能有一些更好的解决方案,但目前该代码可以满足我的需要。 ;-)

【讨论】:

    猜你喜欢
    • 2018-12-08
    • 1970-01-01
    • 1970-01-01
    • 2015-07-13
    • 1970-01-01
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    • 2020-10-24
    相关资源
    最近更新 更多