在我们的数据库表中,我们的refID
和date
列是一个复合主键,标识符的一个字段映射为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
描述为一个简单的列,则代码可以正常工作。为什么?我们该如何处理?我们需要在主键中同时包含
date
和refID
。已添加:
所以我开了新类
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
方法,因此将它们转换为字符串并不像将其强制转换为字符串那样简单。
因此,默认的date
,datetime
和time
类型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/