2016-10-19 4 views
1

私は1対多の関係を持っています。私はマップ(各ブロックは別々のマップ)と部屋(各マップは複数の部屋を持つ)を持っています。だから、エンティティのために、私が持っている(私は情報を切り出す必要はありません):Symfony/Doctrineに1対多のレコードが存在しないことを確認してください

/** 
* Block 
* 
* @ORM\Table(name="BLOCK") 
* @ORM\Entity 
*/ 
class Block 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="PK", type="integer", nullable=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="SEQUENCE") 
    * @ORM\SequenceGenerator(sequenceName="SEQ_GET_BLOCK_PK", allocationSize=1, initialValue=1) 
    * @ORM\OneToMany(targetEntity="Rooms", mappedBy="blockId") 
    */ 
    private $pk; 
} 

/** 
* Rooms 
* 
* @ORM\Table(name="ROOMS", indexes={@ORM\Index(name="IDX_EB2CE87E9B70DE02", columns={"MAP_ID"})}) 
* @ORM\Entity 
*/ 
class Rooms 
{ 
    /** 
    * @var integer 
    * 
    * @ORM\Column(name="PK", type="integer", nullable=false) 
    * @ORM\Id 
    * @ORM\GeneratedValue(strategy="SEQUENCE") 
    * @ORM\SequenceGenerator(sequenceName="SEQ_GET_ROOMS_PK", allocationSize=1, initialValue=1) 
    */ 
    private $pk; 

    /** 
    * @var \Block 
    * 
    * @ORM\ManyToOne(targetEntity="Block") 
    * @ORM\JoinColumns({ 
    * @ORM\JoinColumn(name="BLOCK_ID", referencedColumnName="PK") 
    * }) 
    */ 
    private $block; 

今すぐ部屋に属しているものをブロック得るために、それはコントローラで、簡単です:

$roomRepo = $this->getDoctrine()->getRepository('AppBundle:Rooms'); 
$rooms = $roomRepo->findAll(); 

や小枝に(フィールド名は、ブロックテーブルに別のフィールドです):

{% for room in rooms %} 
    {{ room.block.fieldname }} 
{% endfor %} 

しかし、ブロックのリストを表示し、その下の部屋を表示することが難しくなります。私は次のように小枝にブロックのリストを取得し、何かをできるようにしたいと思います。このような状況で

{% for block in blocks %} 
    {% for room in block.rooms %} 
     {{ room.name }} 
    {% endfor %} 
{% endfor %} 

は、私はそれらの下で任意の部屋を持っていないブロックのリストを取得しようとしています。上記のソリューションがうまくいけば、各ブロックの部屋数をカウントして、空きがない場合にのみ表示することができます。もう1つのオプションは、クエリをcreateQueryBuilderでカウントさせ、エンティティブロックを正しい結果で返すことです。

アイデア?私はこれらの道を見下ろしているが、少し後に壁に当たった。

答えて

2

あなたは一対多の双方向の関係を必要とするように思え:http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/association-mapping.html#one-to-many-bidirectional

Block主キーで$pk財産ですか?そして、それは、注釈@ORM\OneToManyを持っていないことができますし、お部屋のコレクションを持つ別のプロパティが必要です。ご利用の場合のような、まったく同じようだ

/** 
* @ManyToOne(targetEntity="Block", inversedBy="rooms") 
* @JoinColumn(name="BLOCK_ID", referencedColumnName="PK") 
*/ 
private $block; 

Roomクラスの

/** @OneToMany(targetEntity="Rooms", mappedBy="block") */ 
private $rooms; 

、その後にドキュメントのものですので、その例に従うことをお勧めします。

+0

これは正解であり、私のソリューションのオプションではありません(この場合は余分なフィールドを追加したくないため、更新する方法は維持するのが難しいでしょう)。将来的には1対多の方法がありますが、この場合は手動で結合するより複雑なSQLを実装してこれを回避します。 – MicWit

0

Martinが投稿したソリューションを使用することができれば、私の場合は私が望む結果を得るためにもっと複雑なクエリを追加することに決めました。クエリは次のように見てしまった:私は実際にリポジトリにカスタム関数でこれをやった

$blockRepo = $this->getDoctrine()->getRepository('AppBundle:Blocks'); 
$query = $blockRepo->createQueryBuilder('b') 
    ->select('b') 
    ->leftJoin("AppBundle:Rooms", "r", "WITH", "b.pk=r.block") 
    ->where("b.location = :locationId") 
    ->andWhere("r.pk IS NULL") 
    ->setParameter("locationId", $locationId) 
    ->getQuery(); 
$blocks = $query->getResult(); 

が、このコードは動作するはずです。 2つの行(whereとsetParameter)をlocationIdに渡す限り、これは別のフィールドでも選択したかったからです。この2行を省略すると、部屋のないブロックがすべて選択されます。

関連する問題