标识符中的 Doctrine 2 ORM DateTime 字段 [英] Doctrine 2 ORM DateTime field in identifier

查看:13
本文介绍了标识符中的 Doctrine 2 ORM DateTime 字段的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我们的数据库表中,我们的 refIDdate 列是一个复合主键,标识符的一个字段被映射为一个 datetime:

In our DB tables, we columns refID and date are a composite primary key, with one field of the identifier being mapped as a datetime:

class corpWalletJournal
{
    /**
     * @ORMColumn(name="refID", type="bigint", nullable=false)
     * @ORMId
     * @ORMGeneratedValue(strategy="NONE")
     */
    private $refID;

    /**
     * @ORMColumn(name="date", type="datetime", nullable=false)     
     * @ORMId
     * @ORMGeneratedValue(strategy="NONE")
     */
    private $date;

    public function setRefID($refID)
    {
        $this->refID = $refID;
    }

    public function setDate(DateTime $date)
    {
        $this->date = $date;
    }
}

如果我们在实体中将它们描述为@ORMId,此代码将返回异常无法将日期时间转换为字符串"...

If we describe them in entity as @ORMId this code will return exception "cannot convert datetime to string"...

$filter = array(
    'date' => $this->stringToDate($loopData['date']), 
    'refID' => $loopData['refID']
));

$oCorpWJ = $this->em->getRepository('EveDataBundle:corpWalletJournal')->findOneBy($filter);
// ...
$oCorpWJ->setDate($this->stringToDate($loopData['date']));
// ...

如果我们将 corpWalletJournal#date 描述为一个简单的列,代码工作正常.为什么?

If we describe corpWalletJournal#date as a simple column, code works fine. Why?

我们该如何处理?我们需要在主键中同时具有 daterefID.

How can we deal with it? We need to have both date and refID in the primary key.

添加:

所以我创建了一个新类

use DateTime;

class DateTimeEx extends DateTime
{

public function __toString()
{
    return $this->format('Y-m-d h:i:s');
}

}

和它的新类型

use DoctrineDBALTypesType;
use DoctrineDBALPlatformsAbstractPlatform;
use EveDataBundleEntityTypeDateTimeEx;

class DateTimeEx extends Type
{
    const DateTimeEx = 'datetime_ex';

    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
    {
        return 'my_datetime_ex';
    }

    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        return new DateTimeEx($value);
    }

    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        return $value->format('Y-m-d h:i:s');
    }

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

    public function canRequireSQLConversion()
    {
        return true;
    }

}

如何在实体中使用它们?

How can i use them in entity?

我的(编辑过的)类型类

My (edited) Type Class

    use DoctrineDBALTypesType;
use DoctrineDBALPlatformsAbstractPlatform;

class DateTimeEx extends Type
{
    const DateTimeEx = 'datetime_ex';

    public function getSQLDeclaration(array $fieldDeclaration, AbstractPlatform $platform)
    {
        return 'my_datetime_ex';
    }

    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        return $value;
    }

    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        return $value;
    }

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

}

推荐答案

Doctrine 2 ORM 需要将 UnitOfWork.这是让 EntityManager 能够跟踪对象更改所必需的.

Doctrine 2 ORM needs to convert identifier fields to strings in the UnitOfWork. This is required to have the EntityManager being able to track changes to your objects.

因为 DateTime 类型的对象本身不实现方法 __toString,将它们转换为字符串并不像将它们转换为字符串那么简单.

Since objects of type DateTime don't natively implement method __toString, converting them to strings is not as simple as casting them to strings.

因此,默认的datedatetimetime 类型不支持作为标识符的一部分.

Therefore, the default date, datetime and time types are not supported as part of the identifier.

要处理它,您应该定义自己的自定义字段类型 mydatetime 映射到您自己的 MyDateTime 类,该类实现了 __toString.这样,ORM 也可以处理包含对象的标识符.

To deal with it, you should define your own custom field type mydatetime mapped to your own MyDateTime class which implements __toString. That way, the ORM can handle identifiers also if they contain objects.

以下是该类的示例:

class MyDateTime extends DateTime 
{
    public function __toString()
    {
        return $this->format('U');
    }
}

这是自定义 DBAL 类型的示例:

And here's an example of how the custom DBAL type would look like:

use DoctrineDBALTypesDateTimeType;
use DoctrineDBALPlatformsAbstractPlatform;

class MyDateTimeType extends DateTimeType
{
    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        $dateTime = parent::convertToPHPValue($value, $platform);
        
        if ( ! $dateTime) {
            return $dateTime;
        }

        return new MyDateTime('@' . $dateTime->format('U'));
    }

    public function requiresSQLCommentHint(AbstractPlatform $platform)
    {
        return true;
    }

    public function getName()
    {
        return 'mydatetime';
    }
}

然后你在引导过程中用你的 ORM 配置注册它(取决于你使用的框架).在 symfony 中,它记录在 symfony 准则文档中.

Then you register it with your ORM configuration during bootstrap (depends on the framework you are using). In symfony, it is documented on the symfony doctrine documentation.

之后,您可以在实体中使用它:

After that, you can use it in your entities:

class corpWalletJournal
{
    // ...

    /**
     * @ORMColumn(name="date", type="mydatetime", nullable=false)     
     * @ORMId
     * @ORMGeneratedValue(strategy="NONE")
     */
    private $date;

这篇关于标识符中的 Doctrine 2 ORM DateTime 字段的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆