如何(如果可能的话)使用Doctrine2更改实体类型,使用它的类表继承?
比方说,我有一个Person父类类型和两个继承类型Employe和Client.我的系统允许创建一个Person并指定它的类型 - 这很容易实现 - 但我也希望能够将人员从Employe更改为Client,同时保持-level Person信息(它的id和其他相关联记录).
使用Doctrine2有一个简单的方法吗?
我正在使用一个Symfony2/Doctrine应用程序,该应用程序使用类表继承(http://docs.doctrine-project.org/en/2.0.x/reference/inheritance-mapping.html#class-table-inheritance)管理咨询中的投诉.每个Consult都有很多投诉(OneToMany),每种不同类型的投诉都有不同的结构和外观.投诉是一个集合,并使用JS动态添加.
此时,我能够坚持投诉并通过在持久性之前将它们重新设置为Controller中的相应类型来将它们链接到Consults.我遇到了一些问题,我打算将其迁移到表单事件(http://symfony.com/doc/current/cookbook/form/dynamic_form_generation.html)或其他类似的东西来简化流程.
但是,我在这一点上遇到的问题是,我无法使用FormView在视图中显示现有的Complaints,因为表单构建器要求我设置要显示的集合的类型.如果每个Consult只有一种类型的投诉,那就没问题了,但它们可以有多种类型,在表单构建器中设置类型会限制我使用那种类型.
是否有一些方法可以阻止FormView在没有类型的情况下转换为字符串或某种方式在每个投诉的基础上动态检测和分配类型(使用$ complaint-> getComplaintType(),也许)?
<?php
namespace Acme\ConsultBundle\Entity;
class Consult
{
/**
* @ORM\OneToMany(targetEntity="Acme\ConsultBundle\Entity\ComplaintBase", mappedBy="consult", cascade={"persist", "remove"})
*/
protected $complaints;
}
?>
<?php
namespace Acme\ConsultBundle\Entity;
/**
* Acme\ConsultBundle\Entity\ConsultBase
*
* @ORM\Entity
* @ORM\Table(name="ConsultComplaintBase")
* @ORM\HasLifecycleCallbacks
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="complaint_name", type="string")
* @ORM\DiscriminatorMap({
* "ComplaintDefault" = "Acme\ConsultBundle\Entity\ComplaintDefault",
* "ComplaintRosacea" = "Acme\ConsultBundle\Entity\ComplaintRosacea",
* "ComplaintBotox" = "Acme\ConsultBundle\Entity\ComplaintBotox",
* "ComplaintAcne" = "Acme\ConsultBundle\Entity\ComplaintAcne",
* "ComplaintUrticaria" = "Acme\ConsultBundle\Entity\ComplaintUrticaria",
* })
*/
abstract class ComplaintBase
{
/**
* @ORM\ManyToOne(targetEntity="Acme\ConsultBundle\Entity\Consult", inversedBy="complaints")
* @ORM\JoinColumn(name="consult_id", referencedColumnName="id")
*/
protected $consult; …Run Code Online (Sandbox Code Playgroud) forms doctrine single-table-inheritance class-table-inheritance symfony
我的数据库结构如下:
工作:
评论:
WorkComment与Work的ManyToOne关系:
@ManyToOne(targetEntity="Work", inversedBy="comments")
Run Code Online (Sandbox Code Playgroud)
Work与WorkComment有一个OneToMany关系:
@OneToMany(targetEntity="WorkComment", mappedBy="work")
Run Code Online (Sandbox Code Playgroud)
问题是Doctrine在更新架构时给了我这个错误:
[Doctrine\ORM\Mapping\MappingException]
It is illegal to put an inverse side one-to-many or many-to-many association on
mapped superclass 'Acme\...\AbstractImageWork#comments'.
Run Code Online (Sandbox Code Playgroud)
我想这与MappedSuperclass 抽象图像工作有关,它位于Work和PhotoWork之间,但我实际上并没有将这种关系放在MappedSuperclass上,而是放在CTI表上.那么为什么Doctrine会这样呢?
有任何想法吗?
relationship class-table-inheritance mappedsuperclass doctrine-orm
我必须遵循以下设置:父类
/**
* @ORM\Entity()
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="discr", type="string")
*/
abstract class DataCategory
{
/**
* @ORM\Column(name="id", type="integer")
* @ORM\Id
* @ORM\GeneratedValue(strategy="AUTO")
*/
protected $id;
//...
}
Run Code Online (Sandbox Code Playgroud)
以及几个包含对父项的引用的派生类(仅显示一个)
/**
* @ORM\Entity
*/
class MultiCompoundDataCategory extends DataCategory
{
/**
* @ORM\ManyToMany(targetEntity="DataCategory", fetch="EXTRA_LAZY")
* @ORM\JoinTable(name="multi_compound_data_category_data_category",
* joinColumns={@ORM\JoinColumn(name="multi_compound_data_category", referencedColumnName="id")},
* inverseJoinColumns={@ORM\JoinColumn(name="data_category", referencedColumnName="id")})
*/
public $summands;
public function __construct()
{
$this->summands = new ArrayCollection();
}
}
Run Code Online (Sandbox Code Playgroud)
现在,当通过加载所有MultiCompoundDataCategories时
$this->getDoctrine()->getRepository(MultiCompoundDataCategory::class)->findAll(),不仅会发出MultiCompoundDataCategories上的一个选择(在ManyToMany表上使用连接).相反,我得到一个主查询,然后是每个 summand 的一个查询,每个查询都有一个大的胖序列LEFT JOIN(文档也包含有关此问题的警告,我正在大量引用继承树的非叶节点).
顺便说一句: …
我正在开发旅行管理应用程序.有问题的设计如下:
旅游中的每个人都被指定为旅行者.每位旅行者都有护照.现在,旅行者可以是主会员或子会员,具体取决于他是否是家庭主管.MainMember决定像TourPackage这样的东西,他的旅行家庭的总金额等.一个SubMember在旅行时依赖于MainMember.因此,如果删除了MainMember,则还必须删除其所有子成员.
所以,旅行者有护照.(一对一关系)旅行者是主会员或子会员.(Traveler-MainMember和Traveler-SubMember之间的一对一/一)MainMember可能有几个SubMembers.(一对多)子成员只有一个主要成员.(多到一个)
我目前的ERD如下.

如您所见,三个表 - Traveler,MainMember和SubMember - 形成了循环依赖.不过,我不确定它是否会伤害我的应用程序.如果我删除作为MainMember的Traveler,则1.删除Traveler中的记录.2.删除其相关的MainMember记录.3.删除依赖于MainMember的SubMember记录.4.删除子成员的旅行者记录.
虽然它似乎不是问题,但由于Traveler-MainMember删除将始终只删除Traveler-SubMember(s).不过,我对此感觉不好.
任何人都可以指导我更好的设计吗?
更新 -
在等待回复的同时,我根据@ Daveo的回复提出了另一种设计.基本上,Traveler包含自引用外键.SubMember记录将使用它来识别他们的父母.
这是ERD.

现在,正如@Branko指出的那样,我之前的设计中没有循环依赖问题,我想知道哪种设计更好?
另外,通过Hibernate实现哪种设计会更好?我认为第二种方法可能会在通过Hibernate实现时导致复杂性.
我还要感谢关于您喜欢的设计的实现模式(Hibernate实体中的继承等)的一些指示.
database-design erd circular-dependency hibernate-mapping class-table-inheritance
这是我的基本/父实体,设置所以它的子节点使用自己的表.
/**
* @ORM\Entity
* @ORM\Table(name="layer_object")
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"service"="Service", "aircraft"="Aircraft", ...})
*/
class LayerObject {}
飞机实体.一个表现不错的简单孩子
/** * @ORM\Entity * @ORM\Table(name="aircraft") */ class Aircraft extends LayerObject
服务实体.一个复杂的子节点,它本身就是使用单表继承.
/**
* @ORM\Entity
* @ORM\Table(name="service")
* @ORM\InheritanceType("SINGLE_TABLE")
* @ORM\DiscriminatorColumn(name="discr", type="string")
* @ORM\DiscriminatorMap({"ground"="Ground", "onboard"="Onboard"})
*/
class Service extends LayerObject {}
服务实体的子女
/**
* @ORM\Entity
*/
class Ground extends Service {}
app/console doctrine:schema:validate发现没有错误但app/console doctrine:schema:update --force只是不会生成'service'表,应该使用单表继承.似乎简单地忽略了服务实体定义.
当然我可以手动为这个表创建SQL,但是应用程序会增长,在某些时候我将需要使用迁移.
任何人都可以指向某个方向吗?谢谢.
发现重复,但到目前为止还没有答案,请参阅:Doctrine 2多级继承
编辑:
当我为第二级使用类表继承时(@ORM\InheritanceType("JOINED")对于Service实体),它工作得很好.请参阅: …
single-table-inheritance class-table-inheritance symfony doctrine-orm symfony-2.3
我有以下数据库情况:
wp_users (user table generated by wordpress)
ID | user_login | ...
wp_sp_user (extension to the wp_users table)
ID (FK) | surname | address | ...
Run Code Online (Sandbox Code Playgroud)
现在我已经花了好几个小时将这两个表"融合"成一个单独的User实体,例如:
class User {
var ID;
var user_login;
var surname;
var address;
...
}
Run Code Online (Sandbox Code Playgroud)
有没有办法在不修改wp_user表的情况下完成这样的映射(我不想为了更新原因而做)?
wordpress entity doctrine class-table-inheritance doctrine-orm
我正在尝试使用 ActiveRecord 实现多表继承。看起来所有可用的宝石都很旧。我错过了什么吗?是否有任何“本机”方式可以使用 activerecord 来实现这一点?我正在使用 Rails 3.2.3 和 activerecord 3.2.1
我正在查看文件上传宝石,似乎倾向于将所有资产放在单个"资产"表中并使用STI对它们进行子类化.像ImageAsset,VideoAsset,AudioAsset等等.
我是Rails的新手,我从未使用过STI.以前我刚才提出images,videos,audios单独的表.当然,他们可能会分享几个列,但我会说他们也会有一些不同的列(例如,采样率不适用于图像)
在一个"资产"表中填充所有这些的优点:更容易对所有资产运行查询.缺点:表格会变得更快.如果这是一个问题,我想我总是可以在"类型"列上进行分片.此外,我预计所有仅音频列在图像行等上将为空.
我的整个应用程序将基于资产,所以我想确保在做出决定之前我有优点和缺点.有没有人做过STI资产而后悔呢?有没有人做过而且没有后悔(对于大量的资产)?CTI(类表继承)会在这里成为更好的解决方案吗?
activerecord ruby-on-rails single-table-inheritance class-table-inheritance ruby-on-rails-3
我正在尝试实现一个具有类似于下面的表结构的数据库,其中 2 个表是表的子类型。
动物有一个主键,狗和猫有一个引用动物的animal_id的外键。
animal(animal_id, bornAt)
dog(animal_id, barkSound)
cat(animal_id, meowSound)
Run Code Online (Sandbox Code Playgroud)
值得注意的是,dog和cat是不相交的,因此它们不可能在animal中引用相同的animal_id。
有没有办法在给定animal_id的情况下使用SQL代码来确定动物的类型?例如,如果有一只动物_id为4的狗(不知道动物_id 4是狗这一事实),我想通过动物和狗表中的连接检索数据。
我有一个产品表,products
它具有3个字段(名称,模型(PK)和类名)。该类对应于一个表。所以这是一个例子:
产品表:
model | name | class_Name
z123 | Abcd | AMPS
Run Code Online (Sandbox Code Playgroud)
AMPS表:
model | attribute_1 | attribute_2
z123 | blah blah | blah blah
Run Code Online (Sandbox Code Playgroud)
题:
我是否应该有一个包含PK(模型)及其相应类名的表,然后在我的产品表中使用该类ID?有一个表来容纳所有模型及其类的表会更有效吗?
sql database-design relational-database class-table-inheritance
我目前正在开展一个项目,您可以在其中保存讲师和学生的详细信息.我不知道我是否应该使用一个表User或两个表Lecturer和Student.
当您作为讲师登录时,您具有特殊权限作为项目的组管理页面,在加载学生不具备的组页面上.在Usertbl中将有一个列
status在哪里注册,您可以选择成为学生或讲师的页面并输入特殊的讲师代码.我正在使用PHP和mySql.
在摘要中,我应该User为学生和讲师使用1个表,还是有2个单独的表Student和Lecturer表.
附加信息:1门课程可以有很多讲师和学生,但是1名学生将有1门课程,其中讲师有很多课程.
mysql database database-design single-table-inheritance class-table-inheritance
简短的问题:我可以避免为父类的继承类生成外键吗?是否可以在关系所有者而不是父类中设置用于继承映射的鉴别器列?
解释:
我正在设计一个发票模型,其中发票主题可以是以下三种类型之一:
阅读完Doctrine 继承映射后,我认为类表继承是最适合我的需求的。
Invoice如果我可以从到建立关系,映射的超类InvoiceSubject可以更好地满足我的需求,但我认为我不能:
映射超类不能是实体,它不可查询,并且映射超类定义的持久关系必须是单向的(仅具有拥有方)。这意味着在映射的超类上根本不可能存在一对多关联。此外,只有当映射的超类当前仅在一个实体中使用时,多对多关联才有可能。
此外,使用接口可能是一种解决方案,但关系中的接口只能映射到一个实体。
所以,这是我的模型:
/**
* @ORM\Entity
*/
class Invoice
{
/**
* @ORM\ManyToOne(targetEntity="InvoiceSubject")
* @var InvoiceSubject
*/
protected $subject;
}
/**
* @ORM\Entity
* @ORM\InheritanceType("JOINED")
* @ORM\DiscriminatorColumn(name="invoicesubject_type", type="string")
* @ORM\DiscriminatorMap({"invoice-subject" = "InvoiceSubject", "contract" = "Contract", "provider" = "Provider", "client" = "Client"})
*/
class InvoiceSubject
{
/**
* @ORM\Id
* @ORM\Column(type="integer")
*/
protected $id;
}
/**
* @ORM\Entity
*/
class …Run Code Online (Sandbox Code Playgroud) doctrine-orm ×5
doctrine ×3
symfony ×3
activerecord ×2
database ×2
mysql ×2
sql ×2
entity ×1
erd ×1
forms ×1
lazy-loading ×1
php ×1
relationship ×1
symfony-2.3 ×1
wordpress ×1