Inheritance 继承替代主义

Inheritance 继承替代主义,inheritance,doctrine-orm,zend-framework2,Inheritance,Doctrine Orm,Zend Framework2,目前,我们正在使用Zend Framework 2和Doctrine 2开发一个非常灵活和模块化的应用程序。在此应用程序中,存在多个条令实体,例如模块产品中的实体产品。此模块Products是产品管理的基本/默认模块 我们希望能够为客户创建自定义的产品模块(XProducts)。因此,我创建了一个新实体,XProduct(带有一些额外的字段),它扩展了Product 因此,如果启用了自定义模块,我希望使用XProduct和elseProduct,但决不能一起使用(在同一个项目中) 如果我用@En

目前,我们正在使用Zend Framework 2和Doctrine 2开发一个非常灵活和模块化的应用程序。在此应用程序中,存在多个条令实体,例如模块
产品
中的实体
产品
。此模块
Products
是产品管理的基本/默认模块

我们希望能够为客户创建自定义的
产品
模块(
XProducts
)。因此,我创建了一个新实体,
XProduct
(带有一些额外的字段),它扩展了
Product

因此,如果启用了自定义模块,我希望使用
XProduct
和else
Product
,但决不能一起使用(在同一个项目中)

如果我用@Entity注释这两个实体,它将部分工作;例如
findAll
工作正常,但
find
不工作:创建的SELECT语句包含正确的列,但WHERE子句错误。例如:

SELECT t1.id AS id2, t1.name AS name3 FROM products t1 WHERE t0.id = ?
我猜
t1
代表
ProductX
t0
代表
Product
,但我不明白为什么列是正确的(
t1
),而where子句不是(
t0

我知道条令提供了单表继承来实现继承,但是因此有必要拥有一个DiscriminatorColumn并在基本/默认实体中定义DiscriminatorMap。这不适合我们,因为如果我们为客户添加新的自定义模块,我们需要更改基本/默认模块(这不是我们想要的…)


有人知道如何解决这个问题吗?谢谢

我们使用这种模式,并且它与最容易使用的原则一起使用(尽管它可以在面向对象方面做得更好,有很多丑陋的代码)。以我们的模块为例,其中一个
投资组合
实例可以占用多个
项目
实例

我们使用一个
Portfolio
实体,它从映射的超类
AbstractPortfolio
扩展而来。如果客户机需要特殊字段,我们将创建一个扩展映射超类的
ClientPortfolio
,以便正确重载所有属性

类名为,该字符串在示例中使用。您从不加载
公文包
存储库,而是始终加载
客户端公文包
,即使您以默认公文包的名称从服务管理器请求存储库类


此方法可以与存储库函数配合使用(尽管此类是
项的存储库,而不是
组合的存储库)。我不会使用单表继承,因为您不会使用彼此之外的多个实体。至少,这是我们的情况。

我终于解决了这个问题。对于所有默认/基类,我创建了一个额外的抽象MappedSuperclass(如JurianSluiman所述)。例如,对于客户的特定
产品
实体,我需要以下信息:

  • AbstractProduct(包含所有默认/基本功能)
  • Product(默认/基类,为空并扩展AbstractProduct)
  • XProduct(它为我们的客户提供了额外的功能并扩展了AbstractProduct)
要解决MappedSuperclass上的关联问题,请参考抽象类,例如:
@ORM\OneToOne(targetEntity=“ProductManagement\Entity\AbstractProduct”)

然后,我使用条令的EntityResolver(请参阅)将抽象类(或接口)关联映射到真实实体(取决于配置):


通过这种方式,我可以使用客户的特定实体覆盖我的实体,而无需更改默认/基本模块和实体(这正是我所寻找的)。

感谢您的回答。MappedSuperclass听起来很有趣,不过我需要为所有实体(抽象和默认/基类)创建额外的类。但如果它起作用;没关系:)。只有一个问题:MappedSuperclass不能有一对多和一对一的关系,而这正是我不希望的;例如,
ProductGroup
有一个引用自身的父属性。所以我认为使用MappedSuperclass是不可能的。我现在在手机上,所以无法轻松检查它,但上面的公文包模块有一个公文包容器,其中包含项目,具有适当的关系(即一对多)。检查Github存储库,其中应该有一些东西可以让它工作。我在您的模块中可以找到的唯一关系是AbstractItem到Portfolio中的多对一关系。当然,在另一方面,它是一对多关系,但在我的情况下,我想在这方面定义关系,这在MappedSuperclass上不起作用。我尝试相同的方法,但问题是抽象实体类(AbstractProduct)不能用于DQL查询。根据映射,超类是不可查询的。如何编写既适用于Product又适用于XProduct的查询?
'entity_resolver' => array(
    'orm_default' => array(
        'resolvers' => array(
            // Note: Use only one
            'ProductManagement\Entity\AbstractProduct' => 'ProductManagement\Entity\Product', // Default
            'ProductManagement\Entity\AbstractProduct' => 'XProductManagement\Entity\XProduct', // For customer X
        )
    )
)