使用查询构建器在Symfony中查询的结果数不正确

时间:2016-10-11 05:52:42

标签: sql oracle doctrine-orm symfony

我想在连接到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)

确保它是只读的。

1 个答案:

答案 0 :(得分:0)

好的,问题解决了。对于未来陷入困境的人,首先要注意几点: - 使用查询构建器时,请检查是否在正确的字段上设置了ID - 检查是否使用GUID,该字段设置为GUID而不是字符串(如果您使用数据库的自动映射,它将执行) - 如果使用复合键,请确保在两者上都设置了ID,不要使用generatedValue并设置构造函数(参见下文)

所以这种情况下的解决方案......

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

有关复合键的更多信息:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/tutorials/composite-primary-keys.html

请注意,我确实在Doctrine文档中看到只有字符串和整数可用于复合键,但是,到目前为止我发现GU​​ID工作正常(我认为它应该可以从Doctrine 2.1中解决)上)。