如何在DQL中使用DQL中的学说自定义类型



我在Symfony项目中使用Spatie的枚举,并为这些对象制作了自定义的DBAL类型。当我将枚举对象保存到数据库时,我会以特殊的字符串格式保存。我的EnumType中的转换功能看起来像这样:

public function convertToDatabaseValue($value, AbstractPlatform $platform)
{
    if ($value === null) {
        return null;
    }
    return get_class($value) . '::' . $value->getIndex() . '::' . $value->getValue();
}

所以例如,我有一个看起来像这样的交易状态:

namespace AppEnum;
use SpatieEnumEnum;
/**
 * @method static self failed()
 * @method static self pending()
 * @method static self completed()
 */
final class TransactionStatus extends Enum {}

,当我将其保存到数据库时,它可以分别变成这些字符串中的任何一个:

AppEnumTransactionStatus::0::failed
AppEnumTransactionStatus::1::pending
AppEnumTransactionStatus::2::completed

这有助于我的EnumType知道什么枚举将其转换回。我在字符串中使用索引号的原因是因为这有助于分类。

现在,这一切都非常适合获取和将我的实体保存到数据库中。但是,当我尝试在DQL语句的Where子句中使用枚举时,它根本不起作用。

namespace AppRepository;
use AppEntityTransaction;
use AppEnumTransactionStatus;
use SymfonyBridgeDoctrineRegistryInterface;
use DoctrineBundleDoctrineBundleRepositoryServiceEntityRepository;
class TransactionRepository extends ServiceEntityRepository
{
    public function __construct(RegistryInterface $registry)
    {
        parent::__construct($registry, Transaction::class);
    }
    public function findByStatus(TransactionStatus $status)
    {
        return $this->createQueryBuilder('t')
            ->andWhere('t.status = :status')
            ->setParameter('status', $status)
            ->getQuery()->getResult();
    }
}

因为出于某种原因,学说忽略了我的转换功能,而只是使用Spatie枚举中内置的__toString()函数。因此,学说正在寻找字符串"pending"而不是"AppEnumTransactionStatus::1::pending"

我如何确保我的枚举始终在DQL中正确转换?

好吧,我找到了一种方法,即使它超级骇客。我只是从调用 __toString()方法的位置检查,如果是从学说的dbal调用的,则使用枚举的DB格式。

namespace AppEnum;
use SpatieEnumEnum as BaseEnum;
abstract class Enum extends BaseEnum
{
    public function __toString(): string
    {
        if (debug_backtrace()[1]['class'] === 'PDOStatement') {
            return get_class($this) . "::$this->index::$this->value";
        }
        return parent::__toString();
    }
}

相关内容

  • 没有找到相关文章