22

DB テーブルでは、列refIDdateが複合主キーであり、識別子の 1 つのフィールドが としてマップされます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;
    }

}
4

2 に答える 2

44

Doctrine 2 ORMは、識別子フィールドを。内の文字列に変換する必要がありUnitOfWorkます。これはEntityManager、オブジェクトへの変更を追跡できるようにするために必要です。

タイプのオブジェクトはDateTimeメソッドをネイティブに実装しない__toStringため、文字列に変換することは、文字列にキャストするほど簡単ではありません。

したがって、デフォルトdateの、datetimeおよびtimeタイプは、識別子の一部としてサポートされていません

これに対処するには、を実装する独自のクラスにマップされた独自のカスタムフィールドタイプ を定義する必要があります。そうすれば、ORMは、オブジェクトが含まれている場合にも識別子を処理できます。mydatetimeMyDateTime__toString

そのクラスがどのように見えるかの例を次に示します。

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のドクトリンドキュメントに文書化されています。

その後、エンティティで使用できます。

class corpWalletJournal
{
    // ...

    /**
     * @ORM\Column(name="date", type="mydatetime", nullable=false)     
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="NONE")
     */
    private $date;
于 2013-02-26T09:33:17.390 に答える
3

注意してください

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

タイムゾーンは良くありません。やったほうがいい :

$val = new DateTimeEx('@' . $dateTime->format('U'));
$val->setTimezone($dateTime->getTimezone());

return $val;
于 2016-01-26T13:25:56.730 に答える