无法创建一对一关系

Cannot create a OneToOne relationship

我正在使用 Typeorm 并尝试在两个实体之间创建 OneToOne 关系:ProjectResource。 为此我做了:

import { Entity, Column, PrimaryGeneratedColumn, OneToMany, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm';
import { Customer } from './customer';

@Entity()
export class Project {
    @PrimaryGeneratedColumn()
    public id!: number;

    @Column({ nullable: false })
    public name!: string;

    @Column({ nullable: true })
    public description!: string;
    
    @PrimaryColumn({ nullable: false })
    public customer_id!: number;

    @OneToOne(() => Customer)
    @JoinColumn({ name: 'customer_id' })
    public customer!: Customer;

    @Column({ default: false })
    public deleted: boolean = false;
}

然后我有 Resource 个实体:

import { Entity, Column, PrimaryGeneratedColumn, OneToOne, JoinColumn, PrimaryColumn } from 'typeorm';
import { Project } from './project';

@Entity()
export class Resource {
    @PrimaryGeneratedColumn()
    public id!: number;

    @Column({ nullable: false })
    public name!: string;

    @Column()
    public description: string = "";

    @Column()
    public deleted: boolean = false;

    @PrimaryColumn({ nullable: false })
    public project_id!: number;

    @OneToOne(() => Project)
    @JoinColumn({ name: 'project_id' })
    public project!: Project;
}

本质上,一个 Resource 可以关联到一个 Project,所以我在 project 属性 的 project 属性 之上定义了 OneToOne 装饰器16=],然后,我还定义了一个名为 project_id 的列,我的 API 设计需要这些列。

通常 Typeorm 创建 projectId 列,所以我用 name 属性 指定:project_id,我得到的问题是:

message: "ER_DUP_FIELDNAME: Duplicate column name 'project_id'", code: 'ER_DUP_FIELDNAME', errno: 1060, sqlMessage: "Duplicate column name 'project_id'", sqlState: '42S21', index: 0, sql: 'CREATE UNIQUE INDEX REL_1c2e17cbbe9905b63f1f870679 ON resource (project_id, project_id)', name: 'QueryFailedError', query: 'CREATE UNIQUE INDEX REL_1c2e17cbbe9905b63f1f870679 ON resource (project_id, project_id)', parameters: [] }

我能够使用以下方法解决此问题:

@JoinColumn({ name: 'project_id', referencedColumnName: 'id' })

但我不明白为什么在第一个设置中这不起作用,因为我对 Project 实体做了完全相同的操作,特别是链接 Customer table并且有效。

此外,我不确定这是否正确,这些是创建的约束:

这是目前的 ER:

它不起作用,因为您有一个名为 project_id 的字段(@PrimaryColumn)和另一个名为 project 的字段,名称选项设置为 project_id。因此,正如您所看到的,TypeORM 正在尝试创建两个具有相同名称的字段。这是错误的来源。

您可以删除字段 public project_id!: number;因为 TypeORM 加载了关系项目!:项目;自动(如果需要,只有 id 或整个实体)所以它没用。

如果您真的想要关系 ID,请使用 @RelationId 装饰器。

示例如下:

import { Entity, Column, PrimaryGeneratedColumn, OneToOne, JoinColumn, PrimaryColumn, RelationId } from 'typeorm';
import { Project } from './project';

@Entity()
export class Resource {
    @PrimaryGeneratedColumn()
    public id!: number;

    @Column({ nullable: false })
    public name!: string;

    @Column()
    public description: string = "";

    @Column()
    public deleted: boolean = false;

    // CHANGES HERE
    @RelationId((resource: Resource) => resource.project)
    public project_id!: number;

    @OneToOne(() => Project)
    @JoinColumn()
    public project!: Project;
}

希望对您有所帮助:)