我有两个对象:File和FileDetail。一个文件可以有多个FileDetails,但是一个FileDetail只能有一个File。我可以使它正常工作,但是由于关键约束,我无法从数据库中删除任何内容(由于FileDetail依赖于File行,因此无法删除File行,反之亦然)。我有以下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]


理想情况下,我要删除的是文件行,所有子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`))


我将如何获得这种类型的关系(一方面是一对多,另一方面是一对一)。还是我应该将其视为“多对多”?

最佳答案

使用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保留在File端。这样,当您删除文件时,其关联的FileDetail记录也将被删除。我还根据您的原始模式将别名更改为“修订”,因此您可以执行以下操作:

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


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

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

08-25 18:15