下部に更新:
2 つのテーブル間の単純な結合を実行しようとしています。Symfony2 (2.2) を使用して構築している単純なバンド サイト用のギグ テーブルと会場テーブルがあります。Symfony2 と doctrine を使用するのは初めてなので、完全に間違った方向に進んでいる可能性があります。テーブルを作成して DataFixtures を設定し、ID の関係が正しいことを確認しました。私が得ている問題は、結果の DQL クエリの FROM セクションで Gig テーブルが 2 回参照されていることです。これにより、期待している x 数のレコードではなく、同じレコードの複数のインスタンスが返されます。それが起こっているために何が間違っているのかわかりません。また、これを行うためのより簡単な方法があるかもしれませんが、サイトを構築する過程で Symfony2 を独学しているため、すべてのオプションを検討しています。
Gig テーブルには、Gig エンティティで ManyToOne 関係として定義されている Venue テーブルを指すvenue_id が含まれています (以下を参照)。doctrine findAll を使用すると、Gig Entity の Venue クラスが正しく設定されているため、すべてが正常に機能するようです。フロントページに表示される最新のギグのいくつかのフラットビューを作成しようとしているので、結合を使用して必要なフィールドのみを含めようと考えました。
リポジトリクエリは次のとおりです。
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 は次のようになります (ゲッターとセッターは省略しています)。
/**
* 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 プロファイラーから「Explain Query」を取得したところ、次のように表示されました。
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
それが何を意味するのかはわかりませんが、それがどのように使用されたかについての異なる情報を持つ両方のテーブル エントリを示しています。