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

相关:如何在学说2/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

在 Item 中制作$author并让 ItemPacks$author值始终为空。然后你可以这样做:

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

而且你总是得到ItemDVDor的实例ItemCD

于 2013-02-13T12:48:57.197 回答
0

答案既棘手又冗长。我认为实体方法是可以的,通过查询项目实体你会得到你想要的。现在对于表单,您可能需要每个子项目一个 FormType,然后使用表单集合的方法(http://symfony.com/doc/2.1/cookbook/form/form_collections.html),我确定您将需要挂钩到预绑定事件以准备数据。

这是一个快速的想法,也许它可以帮助你。

于 2013-02-13T11:41:39.543 回答