其中,ING在判别表(Where-ing in discriminated tables)

2019-08-16 22:32发布

如何选择从一个特定作者的所有项目? 它可以这样? 或者我怎么可以编辑实体,如果我想很多的项目类型和项目包(项目都有许多项目)吗?

项目

/**
 * @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;

}

ItemCD

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

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

}

ItemDVD

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

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

}

ItemPack

/**
 * @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;

}

Answer 1:

你将不得不查询具体内容。 这是一个已知(并希望)的限制,因为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
                    )
            )
    )


Answer 2:

$author项,并有ItemPacks $author值始终为null。 然后,你可以这样做:

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

而你总是得到的实例ItemDVDItemCD



Answer 3:

这是棘手和漫长的答案。 我认为实体的形式给出正常,并通过查询,你会得到你想要的项目实体。 现在的形式,你可能需要每个子项一个FormType然后用户的形式给出了Form集合( http://symfony.com/doc/2.1/cookbook/form/form_collections.html ),我敢肯定,你将需要挂钩到绑定事件前准备的数据。

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



文章来源: Where-ing in discriminated tables