底部更新:
我正在尝试做应该是两个表之间的简单连接。我有一个 Gig 表和一个 Venue 表,用于我正在使用 Symfony2 (2.2) 构建的一个简单的乐队站点。这是我第一次使用 Symfony2 和教义,所以我可能完全走错了方向。我已经使用 DataFixtures 创建并填充了表,并验证了 ID 关系是否正确。我遇到的问题是,生成的 DQL 查询在 FROM 部分中引用了 Gig 表两次,这导致我返回同一记录的多个实例,而不是我期望的 x 条记录。我不知道我做错了什么才会发生这种情况。此外,可能有一种更简单的方法来做到这一点,但我正在探索我所有的选择,因为我正在自学 Symfony2 在构建站点的过程中。
Gig 表包含一个venue_id,指向一个在Gig 实体中定义为ManyToOne 关系的Venue 表(如下所示)。使用学说 findAll 似乎在正确填充 Gig 实体中的 Venue 类的情况下一切正常。我正在尝试创建一些要在首页上显示的最新 Gig 的平面视图,因此我想我会尝试使用 Join 并仅包含我需要的字段。
这是存储库查询:
public function getGigsWithLimit($maxGigs)
{
$qb = $this->createQueryBuilder('b')
->select('
g.gigDate,
g.startTime,
g.endTime,
g.message1 as gig_message1,
g.message2 as gig_message2,
g.url,
v.name,
v.address1,
v.address2,
v.city,
v.state,
v.zip,
v.phone,
v.url as venue_url,
v.message1 as venue_message1,
v.message2 as venue_message2,
v.message3 as venue_message3'
)
->from('WieldingBassBundle:Gig', 'g')
->leftJoin('g.venue', 'v')
->orderBy('g.gigDate', 'DESC')
->setMaxResults($maxGigs);
return $qb->getQuery()->getResult();
}
这是它创建的 DQL:
SELECT
g0_.id AS id0,
g0_.gig_date AS gig_date1,
g0_.start_time AS start_time2,
g0_.end_time AS end_time3,
g0_.message1 AS message14,
g0_.message2 AS message25,
g0_.url AS url6,
v1_.name AS name7,
v1_.address1 AS address18,
v1_.address2 AS address29,
v1_.city AS city10,
v1_.state AS state11,
v1_.zip AS zip12,
v1_.phone AS phone13,
v1_.url AS url14,
v1_.message1 AS message115,
v1_.message2 AS message216,
v1_.message3 AS message317
FROM
Gig g2_,
Gig g0_
LEFT JOIN
Venue v1_ ON g0_.venue_id = v1_.id
LIMIT
6
Gig g2_是我的问题。如果我删除它并执行查询,一切都按预期进行。我不知道是什么产生的。
第一个表 Gigs Entity 看起来像这样(我省略了 getter 和 setter):
/**
* Gig
*
* @ORM\Table()
* @ORM\Entity(repositoryClass="Wielding\BassBundle\Entity\GigRepository")
* @ORM\HasLifecycleCallbacks
*/
class Gig
{
/**
* @var integer
*
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
private $id;
/**
* @var \DateTime
*
* @ORM\Column(name="gig_date", type="date")
*/
private $gigDate;
/**
* @var \DateTime
*
* @ORM\Column(name="start_time", type="datetime")
*/
private $startTime;
/**
* @var \DateTime
*
* @ORM\Column(name="end_time", type="datetime")
*/
private $endTime;
/**
* @var string
*
* @ORM\Column(name="message1", type="string", length=50, nullable=true)
*/
private $message1;
/**
* @var string
*
* @ORM\Column(name="message2", type="string", length=50, nullable=true)
*/
private $message2;
/**
* @var string
*
* @ORM\Column(name="url", type="string", length=128, nullable=true)
*/
private $url;
/**
* @var integer
*
* @ORM\Column(name="venue_id", type="integer")
*/
private $venueId;
/**
* @ORM\Column(type="datetime")
*/
protected $created;
/**
* @ORM\Column(type="datetime")
*/
protected $updated;
/**
* @ORM\ManyToOne(targetEntity="Venue", cascade="persist")
* @ORM\JoinColumn(name="venue_id", referencedColumnName="id")
*/
protected $venue;
Venue 表很简单,并且没有定义任何关系,因此除非有人要求,否则我会将其省略。
有任何想法吗?谢谢你的帮助。
安德鲁
我删除了所有内容,除了会重现问题的内容,这就是我剩下的内容:
我将存储库方法简化为:
public function getGigsWithLimit2($maxGigs)
{
$qb = $this->createQueryBuilder('a')
->select('g.id')
->from('WieldingBassBundle:Gig', 'g')
->setMaxResults($maxGigs);
return $qb->getQuery()->getResult();
}
这现在生成:
SELECT
g0_.id AS id0
FROM
Gig g1_,
Gig g0_
LIMIT
6
又是那个该死的 Gig g1_ 问题。我从 Symfony 分析器中得到了“解释查询”,它显示:
id select_type table type possible_keys key key_len ref rows Extra
1 SIMPLE g1_ index IDX_ED7D664240A73EBA 4 9 Using index
1 SIMPLE g0_ index IDX_ED7D664240A73EBA 4 9 Using index; Using join buffer
我不假装知道这意味着什么,但它显示了两个表条目,其中包含有关其使用方式的不同信息。