【问题标题】:Doctrine yaml for a One-To-Many And One-To-One RelationshipDoctrine yaml 用于一对多和一对一的关系
【发布时间】:2011-03-10 22:16:11
【问题描述】:

我有两个对象:File 和 FileDetail。一个 File 可以有多个 FileDetails,但一个 FileDetail 只能有一个 File。我可以让它工作,但由于键约束,我无法从数据库中删除任何内容(我无法删除 File 行,因为 FileDetail 依赖于它,反之亦然)。我有以下yaml:

File:
  columns:
    id:
      type: integer
      primary: true
      autoincrement: true
    ...
    fileDetail_id: integer
  relations:
    ...
    FileDetail:
      local: fileDetail_id
      foreign: id
      cascade: [delete]

FileDetail:
  columns:
    id:
      type: integer
      primary: true
      autoincrement: true
    file_id: integer
    ...
  relations:
    ...
    File:
      local: file_id
      foreign: id
      foreignAlias: Revisions
      cascade: [delete]

理想情况下,当我删除 File 行时,所有子 FileDetails 也会被删除。如果我可以手动删除所有 FileDetail 行,然后是 File 行,那就太好了,但是由于关键限制,我无法:

1451 - Cannot delete or update a parent row: a foreign key constraint fails (`file`, CONSTRAINT `file_filedetail_id_file_detail_id` FOREIGN KEY (`filedetail_id`) REFERENCES `file_detail` (`id`))

我如何才能使这种类型的关系发挥作用(一方面是一对多,另一方面是一对一)。还是我应该把它当作双方的多对多?

【问题讨论】:

    标签: php doctrine yaml doctrine-1.2


    【解决方案1】:

    richsage 回答的一个小补充:

    如果您在非拥有方定义关系,Doctrine 可能会在检测此设置时遇到问题。

    一个明显的症状是当您收到一条错误消息,指出在引用表中找不到外键列。 在这些情况下,您可以帮助 Doctrine 在关系中提供“owningSide”属性。以上面的例子为基础:

    File:
      columns:
        id:
          type: integer
          primary: true
          autoincrement: true
        ...
      relations:
        ...
        Revisions:
          class: FileDetail
          local: id
          foreign: file_id
          type: many
          owningSide: false
          cascade: [delete]
    

    【讨论】:

      【解决方案2】:

      @richsage 我对您的解决方案的唯一问题是,对我来说,在 FileDetail: 定义中,file_id: 必须具有 primary: true。

      【讨论】:

        【解决方案3】:

        使用 Doctrine,通常最好只定义一侧(通常是拥有方)的关系,让 Doctrine 解决其余的问题。在这里,您有一个级联删除,看起来是双向的。尝试将架构更改为:

        File:
          columns:
            id:
              type: integer
              primary: true
              autoincrement: true
            ...
          relations:
            ...
            Revisions:
              class: FileDetail
              local: id
              foreign: file_id
              type: many
              cascade: [delete]
        
        FileDetail:
          columns:
            id:
              type: integer
              primary: true
              autoincrement: true
            file_id: integer
        

        并将cascade 仅保留在文件端。这样,当您删除文件时,其关联的 FileDetail 记录也将被删除。我还根据您的原始架构将别名更改为 Revisions,因此您可以这样做:

        $file->Revisions->{some FileDetail field here}
        

        我认为这就是你所追求的。我已从您的文件记录中删除了 filedetail_id 字段,就好像每个文件可以有许多 FileDetail 记录一样,您的文件记录将无法将这些记录的所有 ID 存储在单个整数字段中。

        最后,我已将 type: many 添加到拥有方,因此 Doctrine 从文件方知道这是一对多的关系。

        【讨论】:

          猜你喜欢
          • 2011-02-17
          • 1970-01-01
          • 1970-01-01
          • 2010-12-17
          • 1970-01-01
          • 2018-09-27
          • 1970-01-01
          • 2014-02-13
          • 1970-01-01
          相关资源
          最近更新 更多