Symfony协会将OneToOne和OneToMany映射到同一实体 [英] Symfony Association Mapping OneToOne and OneToMany to Same Entity
问题描述
我有一个表示主页面记录的 实体定义 这个工作,但建议有两个关联与这样一样的实体?还是这是一个很糟糕的主意? 或者,我可以摆脱OneToOne关联,并且只需设置一个ViewRepository函数来获取基于versionId的当前发布版本(就像用于与getVersion()一样的旧映射实体)。这将会起作用,但是它是否内部开销较大,因为它会产生两个查询,否则Doctrine会很聪明,可以优化这一点,就像使用getVersion()一样。 参考资料: 根据@jmather的建议我决定这个模型是好的,因为我需要一个View实体,其他实体可以访问(例如路由指向单个视图的网址,即页面)。 我已将View的OneToOne关系改为单向,因为ViewVersion已经通过其他OneToMany与View关联需要两条路径)。 这允许我为$ view-> getPublished()方便地使用一个简单的方法,似乎更合乎逻辑。 但是,我发现只要$ view-> publishedId设置为视图无法从数据库中删除,因为外键约束(即使它是单向的)。所以我必须打破这个外键链接,然后再删除。我觉得没事。我在此发布了有关此处的详细信息:导致数据库的重叠实体关联删除实体时的外键限制错误 I have a Entity Definitions This "works" but is it recommended to have two associations with the same entity like this? Or is this a really bad idea? The Alternatively, I could get rid of the OneToOne association, and just set a ViewRepository function to get the current published version based on the versionId (just like the old mapped entity used to do with the getVersion()). That would work, but is it more internal overhead, because it would make two queries... or will Doctrine be smart enough to optimize this, just like it did with the getVersion(). NOTE:
These other answers are not complete. References:
http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/working-with-associations.html
http://doctrine-orm.readthedocs.org/en/2.0.x/reference/association-mapping.html#one-to-many-bidirectional Per the advice from @jmather I've decided this model is "okay", because I need a single View entity that other entities can access (e.g. Routing urls that point to a single View, i.e. "page"). I've changed the OneToOne relationship for View to be unidirectional only, because the ViewVersion already has an association back to the View via the other OneToMany (so it doesn't need two paths back). This allows me to keep a simple method for $view->getPublished() handy and seems more logical. However, I've discovered that as long as the $view->publishedId is set the view can't be deleted from the database because of foreign key constraints (even though it's uni-directional). So I have to break that foreign key link before removing. I think that's fine. I posted details about that here: Overlapping Entity Association causing Database Foreign Key Constraint Errors when Removing Entity 这篇关于Symfony协会将OneToOne和OneToMany映射到同一实体的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋! View
实体,然后我有一个关联的实体,名为 ViewVersion
它随着时间的推移存储实体的多个版本。 View
实体在 VersionId $ c $中设置当前的已发布
ViewVersion
c>字段。这使得一个简单的OneToOne关联。但是在某些情况下,我也希望得到与 View
实体相关联的所有版本。如果我想允许用户查看旧版本并恢复。所以我将需要另一个映射,这是OneToMany。第一个 viewVersion
将映射到活动的已发布版本,第二个 viewVersions
将显示所有版本。 / p>
/ **
* @ ORM\Entity
* @ ORM\Table(name =view)
* @ ORM\Entity(repositoryClass =Gutensite\CmsBundle\Entity\ View \ViewRepository)
* /
class View extends Entity\Base {
/ **
* @ ORM\OneToOne(targetEntity =\\ \\ Gutensite\CmsBundle\Entity\View \ViewVersion,inversedBy =view,cascade = {persist,remove},orphanRemoval = true)
* @ ORM\JoinColumn(name =versionId,referencedColumnName =id)
* /
protected $ viewVersion;
/ **
* @ ORM\Column(type =integer,nullable = true)
* /
protected $ versionId = NULL;
/ **
* @ ORM\OneToMany(targetEntity =\Gutensite\CmsBundle\Entity\View\ViewVersion,mappedBy =viewAll,cascade = {persist,remove},orphanRemoval = true)
* /
protected $ viewVersions;
}
/ **
* @ ORM\Entity
* @ ORM\Table(name =view_version)
* @ORM \Entity(repositoryClass =Gutensite\CmsBundle\Entity\View\ViewVersionRepository)
* /
class ViewVersion extends Entity\Base {
/ * *
* @ ORM\OneToOne(targetEntity =\Gutensite\CmsBundle\Entity\View\View,mappedBy =viewVersion,cascade = {persist})
* /
protected $ view;
/ **
* @ ORM\ManyToOne(targetEntity =\Gutensite\CmsBundle\Entity\View\View,inversedBy =viewVersions)
* @ ORM\JoinColumn(name =viewId,referencedColumnName =id)
* /
protected $ viewAll;
/ **
*此版本所属的主视图实体。
* @ ORM\Column(type =integer,nullable = true)
* /
protected $ viewId;
}
ViewVersion
实体将引用单个查看
实体在这两种情况下,映射关联需要两个单独的变量,例如查看
和 ViewAll
。我不完全确定内部协会是如何工作的,以及如何使用映射的参考变量。
http://docs.doctrine-project.org/projects/doctrine-orm /en/latest/reference/working-with-associations.html
http://doctrine-orm.readth edocs.org/en/2.0.x/reference/association-mapping.html#one-to-many-bidirectional
/ **
* @ ORM\Entity
* @ ORM\Table(name =view)
* /
类查看扩展Entity\Base {
/ **
*这是一个OneToOne单向关联,这样我们可以得到
*当前发布的版本很容易,基于publishedId。
* @ ORM\OneToOne(targetEntity =\Gutensite\CmsBundle\Entity\View\TestVersion)
* @ ORM\JoinColumn(name =publishedId,referencedColumnName = id)
* /
protected $ published;
/ **
* @ ORM\Column(type =integer,nullable = true)
* /
protected $ publishedId = NULL;
/ **
*这是所有版本的常规OneToMany双向协会。
* @ ORM\OneToMany(targetEntity =\Gutensite\CmsBundle\Entity\View\ViewVersion,mappedBy =view,cascade = {persist,remove},orphanRemoval = true)
* /
protected $ versions;
}
/ **
* @ ORM\Entity
* @ ORM\Table(name =view_version)
* /
class ViewVersion extends Entity\Base {
/ **
* @ ORM\ManyToOne(targetEntity =\Gutensite\CmsBundle\Entity\\ \\ view \View,inversedBy =versions)
* @ ORM\JoinColumn(name =viewId,referencedColumnName =id)
* /
protected $ view;
/ **
*此版本所属的主视图实体。
* @ ORM\Column(type =integer,nullable = true)
* /
protected $ viewId;
}
View
entity that represents the primary page record, and then I have an associated entity called ViewVersion
which stores multiple versions of the entity as it's changed over time. The View
entity sets the current "Published" ViewVersion
in the VersionId
field. This makes for a simple OneToOne association. But in some contexts I will also want to get all the versions associated with this View
entity, e.g. if I want to allow the user to review older versions and revert back. So I will need another mapping which is a OneToMany. The first viewVersion
will map to the active "published" version, and the second viewVersions
will show all the versions./**
* @ORM\Entity
* @ORM\Table(name="view")
* @ORM\Entity(repositoryClass="Gutensite\CmsBundle\Entity\View\ViewRepository")
*/
class View extends Entity\Base {
/**
* @ORM\OneToOne(targetEntity="\Gutensite\CmsBundle\Entity\View\ViewVersion", inversedBy="view", cascade={"persist", "remove"}, orphanRemoval=true)
* @ORM\JoinColumn(name="versionId", referencedColumnName="id")
*/
protected $viewVersion;
/**
* @ORM\Column(type="integer", nullable=true)
*/
protected $versionId = NULL;
/**
* @ORM\OneToMany(targetEntity="\Gutensite\CmsBundle\Entity\View\ViewVersion", mappedBy="viewAll", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $viewVersions;
}
/**
* @ORM\Entity
* @ORM\Table(name="view_version")
* @ORM\Entity(repositoryClass="Gutensite\CmsBundle\Entity\View\ViewVersionRepository")
*/
class ViewVersion extends Entity\Base {
/**
* @ORM\OneToOne(targetEntity="\Gutensite\CmsBundle\Entity\View\View", mappedBy="viewVersion", cascade={"persist"})
*/
protected $view;
/**
* @ORM\ManyToOne(targetEntity="\Gutensite\CmsBundle\Entity\View\View", inversedBy="viewVersions")
* @ORM\JoinColumn(name="viewId", referencedColumnName="id")
*/
protected $viewAll;
/**
* The primary view entity that this version belongs to.
* @ORM\Column(type="integer", nullable=true)
*/
protected $viewId;
}
ViewVersion
entity will reference a single View
entity in both cases, but the mapped associations need two separate variables, e.g. View
and ViewAll
. I'm not exactly sure how the internals work for the association, and how the reference variable with the mapping is used./**
* @ORM\Entity
* @ORM\Table(name="view")
*/
class View extends Entity\Base {
/**
* This is a OneToOne Unidirectional association, just so that we can get the
* current published version easily, based on the publishedId.
* @ORM\OneToOne(targetEntity="\Gutensite\CmsBundle\Entity\View\TestVersion")
* @ORM\JoinColumn(name="publishedId", referencedColumnName="id")
*/
protected $published;
/**
* @ORM\Column(type="integer", nullable=true)
*/
protected $publishedId = NULL;
/**
* This is the regular OneToMany Bi-Directional Association, for all the versions.
* @ORM\OneToMany(targetEntity="\Gutensite\CmsBundle\Entity\View\ViewVersion", mappedBy="view", cascade={"persist", "remove"}, orphanRemoval=true)
*/
protected $versions;
}
/**
* @ORM\Entity
* @ORM\Table(name="view_version")
*/
class ViewVersion extends Entity\Base {
/**
* @ORM\ManyToOne(targetEntity="\Gutensite\CmsBundle\Entity\View\View", inversedBy="versions")
* @ORM\JoinColumn(name="viewId", referencedColumnName="id")
*/
protected $view;
/**
* The primary view entity that this version belongs to.
* @ORM\Column(type="integer", nullable=true)
*/
protected $viewId;
}