2

我有两个对象: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`))

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

4

3 回答 3

5

使用 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 知道这是来自文件方的一对多关系。

于 2010-07-02T08:03:38.987 回答
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]
于 2012-09-05T12:41:25.793 回答
0

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

于 2011-01-13T20:39:31.847 回答