一对一和一对一关系的学说yaml

时间:2010-07-02 02:28:09

标签: php doctrine yaml doctrine-1.2

我有两个对象:File和FileDetail。文件可以有很多FileDetails,但FileDetail只能有一个文件。我可以让它工作,但由于关键的限制,我无法从数据库中删除任何内容(我无法删除文件行,因为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`))

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

3 个答案:

答案 0 :(得分: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知道它是文件方面的一对多关系。

答案 1 :(得分:1)

富豪的回答:

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

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

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 :(得分:0)

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