如何使用Doctrine 2创建传统的多态关系?
我已经阅读了许多建议使用单表继承的答案,但我无法看到这对我的情况有何帮助。这就是我想要做的事情:
我有一些实用程序实体,如地址,电子邮件和电话号码。
我有一些'可联系'的实体,如客户,雇主,商业。其中每个都应包含与上述实用程序实体的OneToMany关系。
理想情况下,我想创建一个名为'ContactableEntity'的抽象基类,其中包含这些关系,但我知道不可能将OneToMany关系放在带有教义的映射超类中 - 这很好。
但是,如果没有代码中的大量冗余,我仍然不知道如何将它们联系起来。我是否将地址设为STI类型,其中“CustomerAddress”子类包含直接与客户的关系?有没有办法减少重复次数?
答案 0 :(得分:5)
为什么不让您的基本ContactableEntity具体化?
编辑:
在我完成的使用CTI的项目中做了一些实验。我认为没有任何理由认为同一策略不适用于STI。
基本上,我有类似的东西:
/**
* Base class for orders. Actual orders are some subclass of order.
*
* @Entity
* @Table(name="OOrder")
* @InheritanceType("JOINED")
* @DiscriminatorColumn(name="discr", type="string")
* @DiscriminatorMap({"CAOrder" = "CAOrder", "AmazonOrder" = "AmazonOrder"})
*/
abstract class Order {
/**
* CSRs can add notes to orders of any type
* @OneToMany(targetEntity = "OrderNote", mappedBy = "order", cascade={"all"})
* @OrderBy({"created" = "ASC"})
*/
protected $notes;
// ...
}
/**
* @Entity
*/
class AmazonOrder extends Order {
/**
* @Column(type="string", length="20")
*/
protected $amazonOrderId;
// ...
}
/**
* @Entity
*/
class OrderNote {
// ...
/**
* @ManyToOne(targetEntity="Order", inversedBy="notes")
*/
protected $order;
// ...
}
它似乎完全符合预期。我可以得到一个OrderNote,它的$order
属性将包含一些Order的子类。
使用STI是否有一些限制使您无法做到这一点?如果是这样,我建议转到CTI。但我无法想象为什么这对STI无效。
答案 1 :(得分:0)
如果可联系实体是抽象的(@MappedSuperclass),则您需要使用Doctrine 2.2 +提供的ResolveTargetEntityListener
。
它基本上允许您通过指定接口而不是具体实体来定义关系。(也许您想要定义/继承几个接口,因为您说的是多个"可联系人和#34 )。例如,您可以在抽象类或具体类中实现接口。最后,您需要将具体类(实体)定义/关联到config.yml中的相关接口
可以在Symfony文档中找到一个示例:http://symfony.com/doc/current/cookbook/doctrine/resolve_target_entity.html