doctrine-orm - 标识符中的Doctrine 2 ORM DateTime字段

标签 doctrine-orm

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

class corpWalletJournal
{
    /**
     * @ORM\Column(name="refID", type="bigint", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     */
    private $refID;

    /**
     * @ORM\Column(name="date", type="datetime", nullable=false)     
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     */
    private $date;

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

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

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

$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描述为一个简单的列,则代码可以正常工作。为什么?

我们该如何处理?我们需要在主键中同时包含daterefID

已添加:

所以我开了新类
use \DateTime;

class DateTimeEx extends DateTime
{

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

}

和新的类型
use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;
use Eve\DataBundle\Entity\Type\DateTimeEx;

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

}

如何在实体中使用它们?

我的(编辑)类型类别
    use Doctrine\DBAL\Types\Type;
use Doctrine\DBAL\Platforms\AbstractPlatform;

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

}

最佳答案

原则2 ORM需要将标识符字段转换为 UnitOfWork 中的字符串。这是必须的,以便EntityManager能够跟踪对对象的更改。
由于DateTime类型的对象本身并不实现 __toString 方法,因此将它们转换为字符串并不像将其强制转换为字符串那样简单。
因此,默认的datedatetimetime类型are not supported as part of the identifier
为了处理它,您应该定义自己的custom field type mydatetime映射到实现MyDateTime的自己的__toString类。这样,如果ORM包含对象,它们也可以处理标识符。
这是该类的外观示例:

class MyDateTime extends \DateTime 
{
    public function __toString()
    {
        return $this->format('U');
    }
}
这是自定义DBAL类型的示例:
use Doctrine\DBAL\Types\DateTimeType;
use Doctrine\DBAL\Platforms\AbstractPlatform;

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 doctrine documentation上。
之后,您可以在实体中使用它:
class corpWalletJournal
{
    // ...

    /**
     * @ORM\Column(name="date", type="mydatetime", nullable=false)     
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     */
    private $date;

关于doctrine-orm - 标识符中的Doctrine 2 ORM DateTime字段,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15080573/

相关文章:

mongodb - Symfony2 + DoctrineMongoDBBundle 配置

mysql - 从 2 个表中获取数据,在 Doctrine 上没有关系

symfony - 如何使用 Doctrine2 以 yaml 映射格式为表添加注释

json - Doctrine2、PersistentCollection 和 JMS 序列化器

php - 与映射父类(super class)的关联映射

php - 您将如何测试一个可以向查询添加数十个不同过滤器的类?

database - Doctrine Query Builder 不适用于 UPDATE 和 INNER JOIN

doctrine-orm - 为未定义的字段插入 NULL 值的原则

php - 我应该使用 EAV 模型吗?

utf-8 - 使用 Doctrine 2 强制编码和解码