TypeORM:如何显式设置ForeignKey而不具有用于加载关系的属性?

Ser*_*gey 5 foreign-keys typeorm typescript-decorator

我不想创建一个属性来将关系加载到其中(如所有示例所示)。我唯一需要做的就是拥有一个明确的外键属性,以便迁移能够在数据库中为其创建适当的约束。与我需要的装饰器最接近的装饰器是@RelationId,但它仍然需要存在关系类的属性。

为了清楚起见,我们以文档中的示例为例:

@Entity()
export class Post {
    @ManyToOne(type => Category)
    category: Category;

    @RelationId((post: Post) => post.category) // it still requires the presence of the `category` proeprty
    categoryId: number;

}
Run Code Online (Sandbox Code Playgroud)

我不需要category这里的财产。我想拥有的categoryId财产,将其标记为外键Category.Id。它看起来应该像这样:

@Entity()
export class Post {

    @ForeignKey((category: Category) => category.Id) // it's a foreign key to Category.Id
    categoryId: number;

}
Run Code Online (Sandbox Code Playgroud)

可能吗?

cha*_*les 16

“我需要的是有一个明确的外键属性”......

不,你不能。当您使用@ManyToOne装饰器时,TypeOrm将自动创建外键属性。只需将 @ManyToOne 和 @JoinColumn 装饰器组合在一起,如下所示:

@ManyToOne(type => Category)
@JoinColumn({ name: 'custom_field_name_if_you_want' })
category: Category;
Run Code Online (Sandbox Code Playgroud)


小智 6

实际上是可以这样做的:

@Entity()
export class Post {
    // this will add categoryId
    @ManyToOne(type => Category)
    category: Category;

    // and you can use this for accessing post.categoryId
    // only column you mark with @Column decorator will be mapped to a database column 
    // Ref: https://typeorm.io/#/entities
    categoryId: number;

}
Run Code Online (Sandbox Code Playgroud)

添加的内容categoryId不会映射到列,然后将用于显式设置 id 或访问其值,如下所示:

 post.categoryId = 1;
 // or 
 const id = post.categoryId
Run Code Online (Sandbox Code Playgroud)


小智 5

也许您可以创建和编写自己的迁移并像这样使用它:

    const queryRunner = connection.createQueryRunner();
    await queryRunner.createTable(new Table({
        name: "question",
        columns: [
            {
                name: "id",
                type: "int",
                isPrimary: true
            },
            {
                name: "name",
                type: "varchar",
            }
        ]
    }), true);

    await queryRunner.createTable(new Table({
        name: "answer",
        columns: [
            {
                name: "id",
                type: "int",
                isPrimary: true
            },
            {
                name: "name",
                type: "varchar",
            },
            {
                name: "questionId",
                isUnique: connection.driver instanceof CockroachDriver, // CockroachDB requires UNIQUE constraints on referenced columns
                type: "int",
            }
        ]
    }), true);

    // clear sqls in memory to avoid removing tables when down queries executed.
    queryRunner.clearSqlMemory();

    const foreignKey = new TableForeignKey({
        columnNames: ["questionId"],
        referencedColumnNames: ["id"],
        referencedTableName: "question",
        onDelete: "CASCADE"
    });
    await queryRunner.createForeignKey("answer", foreignKey);
Run Code Online (Sandbox Code Playgroud)

此代码片段是从orm 类型的功能测试中提取的,我认为您可以使用它在数据库上创建自己的约束。