Doctrine2 原生查询不支持自定义类型

cea*_*eak 5 php postgresql symfony doctrine-orm zend-framework2

在 ZF2 - PostgreSQL 应用程序中,我想使用 Doctrine2 本机查询来构建分页器列表。

\n\n

因此,如果选择任何自定义 Doctrine / Pgsql 类型,效果会很好。但对于一个查询,我将使用自定义类型的数据。

\n\n

我有一个AlertRecipient在 PostgreSQL 中声明的 Doctrine 2 自定义类型,如下所示:

\n\n
CREATE TYPE alert_recipient AS (\n    email text,\n    status int\n);\n
Run Code Online (Sandbox Code Playgroud)\n\n

这种类型在某些表中使用。表中的示例clients

\n\n
ID (int) | name (varchar) | alerts (alert_recipients[])\n1        | John Doe       | {"(john@doe.com, 1), (jane@doe.com, 1)"} \n2        | Foo Bar        | {"(foo@bar.com, 1)"} \n
Run Code Online (Sandbox Code Playgroud)\n\n

( alert_recipient[]\xc2\xa0 扩展alert_recipient存储许多alert_recipient记录的列表)

\n\n

该类型链接到一个实体,用于水合作用:

\n\n
class AlertRecipient\n{\n    protected $email;\n\n    protected $status;\n\n    // ... with accessors\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

教义类型注册在活动中进行onBoostrap

\n\n
// ...\nif (!Type::hasType(\'alert_recipient\'))\n{\n    Type::addType(\'alert_recipient\', AlertRecipient::class);\n}\n$platform->registerDoctrineTypeMapping(\'alert_recipient\', \'alert_recipient\');\n\nif (!Type::hasType(\'alert_recipient[]\'))\n{\n    Type::addType(\'alert_recipient[]\', AlertRecipients::class);\n}\n$platform->registerDoctrineTypeMapping(\'_alert_recipient\', \'alert_recipient[]\');\n// ...\n
Run Code Online (Sandbox Code Playgroud)\n\n

自定义类型学说适配器已编写,例如文档http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/cookbook/custom-mapping-types.html

\n\n

查询如下所示:

\n\n
$rsm = new ResultSetMappingBuilder($em);\n\n$rsm->addRootEntityFromClassMetadata(Client::class, \'c\');\n// ... some other data from join entity (e.g)\n\n$query = \'SELECT c.* FROM clients c JOIN ...\';\n$em->createNativeQuery($query, $rsm);\n\n$results = $query->getResult(NativeQuery::HYDRATE_ARRAY);\n
Run Code Online (Sandbox Code Playgroud)\n\n

find()问题是我在Doctrine 本机方法或本机查询结果的水合作用中没有相同的行为。

\n\n

在自定义类型适配器中调试:

\n\n
public function convertToPHPValue($value, AbstractPlatform $platform)\n{\n    var_dump($value); exit;\n    // ...\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

编辑

\n\n
public function convertToPHPValueSQL($sqlExpr, $platform)\n{\n    return \'to_json(\' . $sqlExpr . \')\';\n}\n
Run Code Online (Sandbox Code Playgroud)\n\n

find(),结果是使用AlertRecipient实体正确水合的: string \'[{"email":"john@doe.com","status":1}, {"email":"jane@doe.com","status":1}]\'

\n\n

并且从本机查询水合来看,结果[\'order_emails\'] 在实体中没有水合AlertRecipientstring \'{"(john@doe.com, 1), (jane@doe.com, 1)"}\'

\n\n

那么数据没有正确水合......

\n\n

感谢您的想法

\n\n

编辑

\n\n

alertRecipient实体财产申报Client

\n\n
/* @ORM\\Column(type="alert_recipient[]", nullable=true, name="alert_recipients")\n * @Gedmo\\Versioned\n */\n protected $alertRecipients = [];\n\n // ... with accessors \n
Run Code Online (Sandbox Code Playgroud)\n

Wil*_*ilt 0

您是否遵循自定义映射类型的 Doctrine 2 文档

convertToPHPValue您应该使用和等方法convertToDatabaseValue来使水合正常发挥作用。

您还写道:

find(),结果是使用AlertRecipient实体正确水合的......

据我了解,AlertRecipient是一个 dbalType类而不是一个Entity类。

类型类(所以你的AlertRecipient类)应该扩展Doctrine\DBAL\Types\Type.

然后,您应该在使用此类型的实体定义中使用正确的类型属性标记该列:

/** @Column(type="alert_recipient") */
$alertRecipient;
Run Code Online (Sandbox Code Playgroud)

由于您没有共享所有详细信息(例如,使用自定义类型的实体定义),我不确定您哪里出错了,但是如果您按照文档进行操作,所有这些都应该按预期工作,所以我猜您会跳过这些步骤之一。