我遇到了一个问题,也可能放在programmers.stackexchange.com上,但由于它与Doctrine和ZF2非常相关,所以我选择将它放在这里。让我向您介绍我的方案:
BaseEntity
)。BaseEntity
具有属性$cagetory
$category
,实体必须具有其他属性Ab简单示例:
class BaseEntity {
protected $id;
protected $title;
protected $description;
}
class MovieEntity {
protected $id;
protected $title;
protected $description;
protected $airingDateStart; // new property
protected $airingDateEnd; // new property
}
现在我可以很容易地做一个两步式公式,用户首先选择他的类别,并根据将选择EntityClass - 但我不能拥有它。但这并不好,因为如果用户在BaseEntity
- 类别中放置电影然后想要将实体更改为MovieEntity
怎么办?所以这个想法并不是一个安全的选择。
附加要求(使事情变得更复杂)
Category
都通过单个Module
CategoryTable
)到目前为止我做了什么
首先,我选择运行Doctrines功能单表继承。这使我能够轻松地执行MovieEntity extends BaseEntity
之类的操作,并且可以像将魅力添加到数据库一样。但主要问题仍然存在:如果用户更改了类别,它将改变EntityClass,这几乎是一个禁忌。
我的意思是,我可能会以当前的方式做事情,并且在类别的更改上手动修改DiscriminatorColumn
,但这太脏了。
另一种替代方法是,如果更改类别,将创建一个新实体,旧实体将被销毁,但这也有点脏。
总而言之,我认为我走向了错误的方向。可能有一个我不知道的开发模式,这使得我的所有努力工作看起来都是浪费,最终事情变得非常简单,但看起来我忽略了一些东西。
为了更好地了解我的目标,您可以查看我在GitHub上的应用程序:
ItemController#editAction()
可能提供更多关于我打算如何自动制作某些东西的线索。 / LI>
提前感谢我收到的所有反馈。我完全意识到这个问题可能是SO与programmers.stackexchange存在之间的边界,但我毕竟选择了它。
答案 0 :(得分:3)
如果我正确地阅读你的情况,听起来你可以通过避免对Thing的继承而更好地服务,而是将类别特定属性作为事物和类别之间关系的属性。
这样的架构怎么样:
<?php
class Category {
protected $id;
protected $title;
protected $things; //@ManyToOne(targetEntity="ThingCategory")
}
class Thing {
protected $id;
protected $title;
protected $description;
protected $category; //@ManyToOne(targetEntity="ThingCategory")
}
/**
* Use [Single|Class]-Table Inheritence to model subject-category attributes.
*
* ThingCategory is just a base class. Modules provide concrete subclasses
* that encapsulate category-specific attributes.
*/
class ThingCategory {
protected $id; //surrogate key, not strictly necessary
protected $thing; //@ManyToOne(targetEntity="Thing")
protected $category //@ManyToOne(targetEntity="Category")
}
class ThingMovieCategory extends ThingCategory{
protected $airingStartDate;
protected $airingEndDate;
}
class ThingCarCategory extends ThingCategory {
protected $horespower;
protected $numberOfDoors;
protected $color;
}
因此,现在事物可以通过替换与之关联的ThingCategory实体在类别之间移动。事物的身份永远不会改变,只是它与类别的关系。包含在该类别中的必要属性是ThingCategory关系实体的属性,而不是Thing本身的属性。
编辑:您可能遇到的问题是,在子类化实体时,没有记录的修改鉴别器映射的方法。不幸的副作用是你的基础模块必须知道每个可能的模块。但这可能不是一个大问题。如果是的话,我相信可以通过让每个模块操纵基本实体的ClassMetaData来避免这种情况,但我从来没有打扰到实际的工作。
答案 1 :(得分:1)
你的问题就是这句话“但主要的问题仍然存在:如果用户更改了类别,它将改变EntityClass,这几乎是一个禁忌。”
一个类别不会真正改变,它将被删除,并替换为一个新类别。因此,在您的代码中反映这一点,创建一个新实体,持久化,更新所有引用以指向新实体,然后删除旧实体。