在 symfony/doctrine 的 schema.yml 中,我应该在哪里放置 onDelete: CASCADE 用于多对多关系?
Posted
技术标签:
【中文标题】在 symfony/doctrine 的 schema.yml 中,我应该在哪里放置 onDelete: CASCADE 用于多对多关系?【英文标题】:In symfony/doctrine's schema.yml, where should I put onDelete: CASCADE for a many-to-many relationship? 【发布时间】:2009-09-28 17:02:22 【问题描述】:我在我的 Symfony(使用原则)项目中定义了 Orders
和 Upgrades
之间的多对多关系(Order
可以与零个或多个 Upgrades
关联,Upgrade
可以应用于零个或多个Orders
)。
# schema.yml
Order:
columns:
order_id: ...
relations:
Upgrades:
class: Upgrade
local: order_id
foreign: upgrade_id
refClass: OrderUpgrade
Upgrade:
columns:
upgrade_id: ...
relations:
Orders:
class: Order
local: upgrade_id
foreign: order_id
refClass: OrderUpgrade
OrderUpgrade:
columns:
order_id: ...
upgrade_id: ...
我想设置删除级联行为,这样如果我删除Order
或Upgrade
,所有相关的OrderUpgrades
都会被删除。我在哪里放onDelete: CASCADE
?通常我会把它放在关系部分的末尾,但这似乎意味着在这种情况下删除Orders
会级联删除Upgrades
。如果我将onDelete: CASCADE
放在 schema.yml 的上述关系部分中,Symfony + Doctrine 是否足够聪明,可以知道我想要什么?
【问题讨论】:
【参考方案1】:经过多次试验和错误,我能够让它工作的唯一方法是按照 Jestep 评论中的建议并将包括 onDelete: CASCADE 在内的关系定义移动到链接表,所以最后它看起来像这样并按照我的意愿行事(删除从 Order 到 OrderUpgrade 以及从 Upgrade 到 OrderUpgrade 的级联):
# schema.yml
Order:
columns:
order_id: ...
Upgrade:
columns:
upgrade_id: ...
OrderUpgrade:
columns:
order_id: type: integer, notnull: true, primary: true
upgrade_id: type: integer, notnull: true, primary: true
relations:
Order:
onDelete: CASCADE
Upgrade:
onDelete: CASCADE
我必须说,我对互联网上所有不同的 Doctrine Many-to-Many YML 示例感到有些不知所措,每个示例的关系都略有不同。令人沮丧的经历。
【讨论】:
【参考方案2】:我几乎总是使用 Propel,但它应该基本相同。使用:onDelete:级联
应该是:
Order:
columns:
order_id: ...
relations:
Upgrades:
onDelete: CASCADE
class: Upgrade
local: order_id
foreign: upgrade_id
refClass: OrderUpgrade
【讨论】:
只是为了确认所需的行为:使用此规范,如果我删除升级,它将删除相关的订单升级,但不会删除任何订单? 其实onDelete: CASCADE应该在Upgrade表而不是Orders表,再看一遍。但是,鉴于 m2m 关系,这可能根本行不通。我对这个设置不理解的是,为什么你没有一个 Orders 表、一个 Upgrades 表并且没有 OrderUpgrade 和另一个 2 的外键。我看不到整个画面,但它似乎会减少这很复杂。 我起初尝试过,但无法让教义:构建模型和教义:构建sql工作,直到我根据此页面定义 m2m 关系:doctrine-project.org/documentation/manual/1_0/en/… +1 onDelete 配置在 SF 1.4 中对我有用。谢谢。【参考方案3】:每次我需要级联多对多关系并找到不完整的答案时,我都厌倦了在谷歌上搜索它,所以这是我对它的看法,这是迄今为止最完整的。
经过一个简单的测试,我认为您应该定义所有 3 个实体中的关系。 - 仅在您想要加入的 2 个实体中执行此操作效果很好,但级联部分除外。 - 仅在连接表 (OrderUpgrade) 中执行此操作,但您不会获得在 2 个实体中生成的表单和表单过滤器代码。 - 在所有 3 个实体中执行此操作将为您带来两全其美。
在以下示例中,虽然很冗长,但我更喜欢这样: - 如果你删除一个Property,对应的PropertyLandlord条目被删除,而Landlord条目保持不变。 - 如果你删除一个房东,同样的事情。 - 如果您删除 PropertyLandlord 记录,它只会删除链接条目并且保持不变,我猜这是我们最希望寻找的行为。
Property:
columns:
id:
type: integer(8)
primary: true
autoincrement: true
title:
type: string(255)
notnull: true
relations:
Landlords:
class: Landlord
local: property_id
foreign: landlord_id
refClass: PropertyLandlord
Landlord:
columns:
id:
type: integer(8)
primary: true
autoincrement: true
title:
type: string(255)
notnull: true
relations:
Properties:
class: Property
local: landlord_id
foreign: property_id
refClass: PropertyLandlord
onDelete: CASCADE
PropertyLandlord:
columns:
property_id:
type: integer(8)
primary: true
notnull: true
landlord_id:
type: integer(8)
primary: true
notnull: true
relations:
Property:
local: property_id
foreign: id
class: Property
onDelete: CASCADE
Landlord:
local: landlord_id
foreign: id
class: Landlord
onDelete: CASCADE
【讨论】:
只是让您知道,如果模型已经被使用并且您正在修改架构并希望生成-迁移-diff..这可能无法正常工作。 好的,希望最后一次自我评论。如果您确实使用迁移,则需要修改生成的代码,该代码可能会尝试删除现有外键并创建附加数字的新外键,除了级联部分外,这些数字看起来与以前相同。奇怪的是,重复使用相同的 fk 名称(不带附加部分),并可能将创建移动到另一个文件,并且它可以工作!以上是关于在 symfony/doctrine 的 schema.yml 中,我应该在哪里放置 onDelete: CASCADE 用于多对多关系?的主要内容,如果未能解决你的问题,请参考以下文章