与 Doctrine2 的多态关系

发布于 2024-12-11 18:36:52 字数 377 浏览 0 评论 0原文

如何使用原则 2 创建传统的多态关系?

我读过很多建议使用单表继承的答案,但我看不出这对我的情况有什么帮助。这就是我想要做的:

我有一些实用实体,例如地址、电子邮件和电话号码。

我有一些“可联系”的实体,例如客户、雇主、企业。其中每个都应包含与上述实用程序实体的 OneToMany 关系。

理想情况下,我想创建一个名为“ContactableEntity”的抽象基类,其中包含这些关系,但我知道不可能将 OneToMany 关系放入具有学说的映射超类中 - 这很好。

然而,我仍然不知道如何在没有大量代码冗余的情况下将这些联系起来。我是否将地址设为 STI 类型,并使用包含直接与客户的关系的“CustomerAddress”子类?有没有办法减少重复次数呢?

How do I create traditional polymorphic relationships with Doctrine 2?

I have read a lot of answers that suggest using Single Table Inheritance but I can't see how this would help in my situation. Here's what I'm trying to do:

I have some utility entities, like an Address, an Email and a PhoneNumber.

I have some 'contactable' entities, like a Customer, Employer, Business. Each of these should contain a OneToMany relationship with the above utility entities.

Ideally, I'd like to create an abstract base class called 'ContactableEntity' that contains these relationships, but I know it is not possible to put OneToMany relationships in mapped superclasses with doctrine-- that's fine.

However, I am still at a loss at how I can relate these without massive redundancy in code. Do I make Address an STI type, with a 'CustomerAddress' subclass that contains the relationship directly to a Customer? Is there no way to reduce the amount of repetition?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

骄兵必败 2024-12-18 18:36:52

为什么不直接让你的基础 ContactableEntity 具体化呢?

编辑:

刚刚在我完成的使用 CTI 的项目中做了一些实验。我认为同样的策略没有任何理由不适用于性传播感染。

基本上,我有类似的东西:

/**                                                                                                                                                                                                                                                                                      
 * 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。但我无法想象为什么这不适用于性传播感染。

Why not just make your base ContactableEntity concrete?

EDIT:

Just did a few experiments in a project I've done that uses CTI. I don't see any reason that the same strategy wouldn't work with STI.

Basically, I have something like:

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

    // ...
}

And it seems to work exactly as expected. I can get an OrderNote, and it's $order property will contain some subclass of Order.

Is there some restriction on using STI that makes this not possible for you? If so, I'd suggest moving to CTI. But I can't imagine why this wouldn't work with STI.

压抑⊿情绪 2024-12-18 18:36:52

如果可联系实体是抽象的 (@MappedSuperclass),则需要使用 Doctrine 2.2+ 提供的 ResolveTargetEntityListener

它基本上允许您通过指定接口而不是具体实体来定义关系。(当您谈到多个“可联系对象”时,也许您想要定义/继承多个接口)。例如,您可以在抽象类或具体类中实现接口。最后,您需要在 config.yml 中定义/关联具体类(实体)到相关接口。

可以在 Symfony 文档中找到示例: http://symfony.com/doc/current/cookbook/doctrine/resolve_target_entity.html

If the contactable entity shall be abstract (@MappedSuperclass) you'll need to use the ResolveTargetEntityListener provided by Doctrine 2.2+.

It basically allows you to define a relationship by specifying an interface instead of a concrete entity. (Maybe you want to define/inherit several interfaces as you speak of multiple "contactables"). For instance you then can implement the interface in your abstract class or concrete class. Finally you'll need to define/associate the concrete class (entity) to the related interface within the config.yml

An example can be found in the Symfony docs: http://symfony.com/doc/current/cookbook/doctrine/resolve_target_entity.html

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文