2

特定の著者からすべてのアイテムを選択するにはどうすればよいですか? このように可能ですか?または、多くのアイテム タイプとアイテム パッケージ (アイテムには多くのアイテムがある) が必要な場合、エンティティを編集するにはどうすればよいですか?

アイテム

/**
 * @ORM\Table()
 * @ORM\Entity
 * @ORM\InheritanceType("JOINED")
 * @ORM\DiscriminatorColumn(name="discr", type="string")
 * @ORM\DiscriminatorMap({
 * "cd"   = "ItemCD",
 * "dvd"   = "ItemDVD",
 * "pack" = "ItemPack",
 * })
 */
class Item
{

    /**
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     */
    private $id;

    /**
     * @ORM\Column(name="name", type="string", length=250, nullable=false)
     */
    private $name;

}

アイテムCD

/**
 * @ORM\Table()
 * @ORM\Entity
 */
class ItemCD extends Item
{

    /**
     * @ORM\ManyToOne(targetEntity="Author", inversedBy="item")
     * @ORM\JoinColumn(name="author_id", referencedColumnName="id")
     */
    private $author;

}

アイテムDVD

/**
 * @ORM\Table()
 * @ORM\Entity
 */
class ItemDVD extends Item
{

    /**
     * @ORM\ManyToOne(targetEntity="Author", inversedBy="item")
     * @ORM\JoinColumn(name="author_id", referencedColumnName="id")
     */
    private $author;

}

アイテムパック

/**
 * @ORM\Table()
 * @ORM\Entity
 */
class ItemPack extends Item
{

    /**
     * @ORM\ManyToMany(targetEntity="Item", inversedBy="item")
     * @ORM\JoinTable()
     */
    private $items;

}

著者

/**
 * @ORM\Table()
 * @ORM\Entity
 */
class Author
{

    /**
     * @ORM\Column(name="id", type="integer", nullable=false)
     * @ORM\Id
     * @ORM\GeneratedValue(strategy="IDENTITY")
     *
     */
    private $id;

    /**
     * @ORM\Column(name="name", type="string", length=250, nullable=false)
     */
    private $name;

}
4

3 に答える 3

7

特定の要素を照会する必要があります。DQL は静的型付き言語であるため、これは既知の (そして必要な) 制限です: http://www.doctrine-project.org/jira/browse/DDC-16を参照してください。

関連:doctrine2 / dqlクエリで継承されたテーブルのフィールドにアクセスする方法

回避策でこれを処理する方法は、DQL で 2 つのサブクエリを使用することです。

SELECT
    i
FROM
    Item i
WHERE
    i.id IN(
        SELECT 
            i2.id
        FROM
            ItemDvd i2
        WHERE
            i2.author = :author
    )
    OR
    i.id IN(
        SELECT
            i3.id
        FROM
            ItemCd i3
        WHERE
            i3.author = :author
    )

ご覧のとおり、考えられる各サブタイプの識別子を手動で抽出する必要があります。

編集: 特定の作成者からすべてのパックを (単一の DVD または CD とともに) 取得するには、クエリはさらに悪化します。

SELECT
    i
FROM
    Item i
WHERE
    i.id IN(
        SELECT 
            i2.id
        FROM
            ItemDvd i2
        WHERE
            i2.author = :author
    )
    OR
    i.id IN(
        SELECT
            i3.id
        FROM
            ItemCd i3
        WHERE
            i3.author = :author
    )
    OR
    i.id IN(
        SELECT
            i4.id
        FROM
            ItemPack i4
        JOIN
            i4.items i5
        WHERE
            i5.id IN (
                SELECT
                    i6.id
                FROM
                    Item i6
                WHERE
                    i6.id IN(
                        SELECT 
                            i7.id
                        FROM
                            ItemDvd i7
                        WHERE
                            i7.author = :author
                    )
                    OR
                    i6.id IN(
                        SELECT
                            i8.id
                        FROM
                            ItemCd i8
                        WHERE
                            i8.author = :author
                    )
            )
    )
于 2013-02-13T12:53:40.837 に答える
1

$authorアイテムを作成し、ItemPacks値$authorを常に null にします。次に、次のことができます。

$em->findBy("Item", array("author" => $author));

そして、常にItemDVDorのインスタンスを取得しますItemCD

于 2013-02-13T12:48:57.197 に答える
0

それはトリッキーで長い答えです。エンティティのアプローチは問題ないと思います。項目エンティティをクエリすることで、必要なものが得られます。フォームの場合、おそらくサブアイテムごとに 1 つの FormType が必要になり、フォーム コレクション ( http://symfony.com/doc/2.1/cookbook/form/form_collections.html ) のアプローチを使用します。データを準備するには、プレバインド イベントにフックする必要があります。

これは簡単な考えです。役立つかもしれません。

于 2013-02-13T11:41:39.543 に答える