【问题标题】:In symfony/doctrine's schema.yml, where should I put onDelete: CASCADE for a many-to-many relationship?在 symfony/doctrine 的 schema.yml 中,我应该在哪里放置 onDelete: CASCADE 用于多对多关系?
【发布时间】:2009-09-28 17:02:22
【问题描述】:

我在我的 Symfony(使用原则)项目中定义了 OrdersUpgrades 之间的多对多关系(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: {...}

我想设置删除级联行为,这样如果我删除OrderUpgrade,所有相关的OrderUpgrades 都会被删除。我在哪里放onDelete: CASCADE?通常我会把它放在关系部分的末尾,但这似乎意味着在这种情况下删除Orders 会级联删除Upgrades。如果我将onDelete: CASCADE 放在 schema.yml 的上述关系部分中,Symfony + Doctrine 是否足够聪明,可以知道我想要什么?

【问题讨论】:

    标签: database-design orm symfony1 doctrine data-modeling


    【解决方案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 名称(不带附加部分),并可能将创建移动到另一个文件,并且它可以工作!
      猜你喜欢
      • 1970-01-01
      • 2011-06-20
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-01-08
      • 2021-10-29
      相关资源
      最近更新 更多