原则将实体映射到ID,ID映射到实体

时间:2019-09-27 11:29:42

标签: symfony orm doctrine-orm doctrine mapping

正如标题中所述,我想将一个对象转换为一个ID(整数/字符串),然后从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获得的事件管理器。还是有更好的方法?

2 个答案:

答案 0 :(得分:0)

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

doctrine.yaml

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

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;
    }
}

答案 1 :(得分:0)

我找到了一个合适的解决方案,而没有修改任何类来注入一些服务。类型映射类会触发一个事件,并且转换是在外部处理的。

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();
    }

    // ...
}

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