我想在连接到Oracle数据库的Symfony中使用Doctrine中的查询构建器进行查询。我试图在控制器中使用此代码获取当前任何预订的结果:
$bookRepo = $this->getDoctrine()
->getRepository('AppBundle:VScheduledRoomActivity');
$now = new \DateTime();
$curBookDataQuery = $bookRepo->createQueryBuilder("c");
$curBookDataQuery
->where('c.startStamp < :now')
->andWhere('c.endStamp > :now')
->setParameter('now', $now)
;
$curBookData = $curBookDataQuery->getQuery()->getResult();
这应该返回所有当前预订,应该是5(我在Oracle SQL Developer中有效地运行了相同的查询),但只有1个回来了。我查询了问题并且总是得到的结果比我想要的要少。
那么我想如果我将findAll与查询构建器进行比较,其中没有任何内容。所以我修改了代码看起来像这样:
$bookRepo = $this->getDoctrine()
->getRepository('AppBundle:VScheduledRoomActivity');
$curBookDataQuery = $bookRepo->createQueryBuilder("c");
$curBookData = $curBookDataQuery->getQuery()->getResult();
$curBookData2 = $bookRepo->findAll();
因此,当我使用dump()来检查返回的内容时,$ curBookData有15个结果,$ currBookData2有915个结果。这些应该是完全相同的结果!
有没有人遇到过这个问题或有任何想法如何解决?
更新: 我已经找到了更多信息,我相信它与ID有关。在Missing rows when querying table with Doctrine (Symfony2)我看到这是主键的一个问题,当我查看它时,Doctrine已经将主键(我先做数据库)设置为名为occurrence _no的字段。这不是一个关键,因为它用于跟踪重复预订(它和整数),主键是activity_id。所以我用了
@ORM\Id
在此字段上将其设置为主键。然后将其更改为9个结果。我看到它有一种字符串,所以我编辑了这些行:
@var string
@ORM\Column(name="ACTIVITY_ID", type="string", nullable=true)
到
@var guid
@ORM\Column(name="ACTIVITY_ID", type="guid", nullable=false)
并添加了
@ORM\GeneratedValue(strategy="UUID")
现在它显示了67个结果!我认为这与主键是GUID有关,因为在编辑这些细节时结果的数量发生了变化。
另一个注意事项:这是一个视图,我已经使用了
@ORM\Entity(readOnly=true)
确保它是只读的。
答案 0 :(得分:0)
所以这种情况下的解决方案......
问题1 - 我使用的是其他人创建的视图,并假设GUID是主键。这是一个错误的假设,它是一个复合键,整数作为键的第二部分。 问题2 - 数据在到达视图时以某种方式产生了一些重复,因此一些复合键不是唯一的。在进一步刷新数据之后,它似乎带来了正确的值。
查询构建器背景: 从一些研究中我发现,使用像findAll()这样的东西可以在主键不唯一的情况下使用。但是,查询生成器通过主键生成结果DISTINCT,因此如果主键未正确定义或由于某些原因加倍,那么您将不会获得任何具有重复项的行。
要设置复合键,我做了:
/**
* @var integer
*
* @ORM\Column(name="OCCURRENCE_NO", type="integer", nullable=false)
* @ORM\Id
*/
private $occurrenceNo;
/**
* @var guid
*
* @ORM\Column(name="ACTIVITY_ID", type="guid", nullable=false)
* @ORM\Id
*/
private $activityId;
public function __construct($occurrenceNo, $activityId)
{
$this->occurrenceNo= $occurrenceNo;
$this->activityId= $activityId;
}
请注意,我确实在Doctrine文档中看到只有字符串和整数可用于复合键,但是,到目前为止我发现GUID工作正常(我认为它应该可以从Doctrine 2.1中解决)上)。