【问题标题】:From Array to Doctrine/ArrayCollection: entity id (date) issue从 Array 到 Doctrine/ArrayCollection:实体 id(日期)问题
【发布时间】:2015-01-09 09:40:46
【问题描述】:

我有这种情况

实体

class Foo
{
  /**
   * @ORM\Id
   * @ORM\Column(type="date")
   */
  protected $date;

  /**
   * @ORM\Id
   * @ORM\ManyToOne(targetEntity"Bar", inversedBy="foo")
   */
  protected $bar;

  [...]
}

存储库

class FooRepository extends EntityRepository
{
  public function dummyNameFunction()
  {
    $q = $this->createQueryBuilder('foo')
               ->//some dummy "components" added to builder
               ->getQuery()
    ;

    //I need an ArrayCollection as I want to take advantage of
    //Doctrine's ArrayCollection filter() function
    return new ArrayCollection($q->getResult()); 
  }
}

问题

只要我尝试从 db 中获取数据,我就会得到这个错误

ContextErrorException:可捕获的致命错误:DateTime 类的对象 无法转换为字符串 /path/to/project/vendor/doctrine/orm/lib/Doctrine/ORM/UnitOfWork.php 第 2504 行

对我来说这是“非常清楚”:从对象的Array 转换为ArrayCollection,Doctrine 想用实体的 id 索引全新的ArrayCollection,但是,因为关键是日期时间, PHP 本身没有提供__toString() 方法(或等效方法)。

我想到的可能解决方案:

  • 添加一个整数字段作为 id。从 $date$bar 中删除 id 并设置约束以使它们唯一。缺点:我有一个完全没用的文件。
  • Register 一种学说自定义映射类型,基本上是带有 __toString 魔术方法的 Date。缺点:我现在不知道这是否有效,因为我还没有尝试过。。第二个解决方案似乎有效,但不适用于 __toString() 魔术方法。这有点“黑客”,有点脏。您可以在下面找到解决方案 (*)

问题

  1. 与我的两种可能的解决方案相比,有人知道更好或“更快”的方法吗?
  2. (附带问题)这是一个“真正的”问题吗? Doctrine2 devel 可能没有考虑将日期作为键?

脏溶液(*)

首先你需要定义一个 Doctrine2 服装类型。你怎么能这样做?
我在 Doctrine\DBAL\Types 的包内创建了一个文件夹(以保持 Doctrine2 原始包结构的安全)。然后,在里面,我创建了这个类

<?php

namespace Company\BundleName\Doctrine\DBAL\Types;

use Doctrine\DBAL\Types\DateType;
use Doctrine\DBAL\Platforms\AbstractPlatform;

class CustomDate extends DateType
{
    private $date_value;

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

    public function convertToPHPValue($value, AbstractPlatform $platform)
    {
        $date = parent::convertToPHPValue($value, $platform);
        $this->date_value = $date;

        return $date->format('Y-m-d');
    }

    public function convertToDatabaseValue($value, AbstractPlatform $platform)
    {
        return ($value !== null)
            ? $value : null;
    }
}

然后我添加了一个 boot() 方法来捆绑引导文件(您需要在 AppKernel.php 中注册捆绑的文件)

public function boot()
{
    $em = $this->container->get('doctrine.orm.entity_manager');
    Type::addType('custom_date', 'Company\BundleName\Doctrine\DBAL\Types\CustomDate');
    $em->getConnection()->getDatabasePlatform()->registerDoctrineTypeMapping('custom_date','custom_date');
}

在那之后,我有了 mod。 Foo 的$date 变量的映射

  /**
   * @ORM\Id
   * @ORM\Column(type="custom_date")
   */
  protected $date;

注意:如果你使用任何类型提示,记得正确更改getter和setter

【问题讨论】:

  • 根据我的经验,使用auto_increment ids 作为表的主键总是一个好主意...任何其他字段都会让您头疼。
  • @OscarPérez:如果他们给你机会使用其他类型的 id(s) 我相信这些类型和整数一样可以正常工作,所以我在这里等待知道如何修复的人无需添加额外的字段。来吧,应该有方法的! :) PS.:更新了我的问题,第二种方法没有奏效

标签: symfony doctrine-orm


【解决方案1】:

似乎唯一的解决方案是创建一个全新的学说类型(我在这里称之为“肮脏的解决方案”),因为 UnitOfWork 需要字符串或整数才能正常工作。

来源:Doctrine 2 ORM DateTime field in identifier

【讨论】:

    猜你喜欢
    • 2020-01-27
    • 1970-01-01
    • 1970-01-01
    • 2013-12-28
    • 2017-08-14
    • 1970-01-01
    • 2011-10-17
    • 2011-12-12
    • 1970-01-01
    相关资源
    最近更新 更多