【问题标题】:TypeORM: How to set ForeignKey explicitly without having property for loading relations?TypeORM:如何在没有加载关系的属性的情况下显式设置 ForeignKey?
【发布时间】:2019-08-05 20:13:48
【问题描述】:

我不想创建用于将关系加载到其中的属性(如所有示例所示)。我唯一需要的是拥有一个显式外键属性,以便迁移 能够在数据库中为其创建适当的约束。最接近我需要的装饰器是@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;

}

我在这里不需要category 属性。我想拥有categoryId 属性并将其标记为外键Category.Id。它应该是这样的:

@Entity()
export class Post {

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

}

有可能吗?

【问题讨论】:

  • 嘿,你有办法解决这个问题吗?
  • 对不起,伙计,我在一年前改变了我的技术栈。我相信我当时没有找到解决办法。
  • 是的,我根据 charles 解决方案找到了它。

标签: foreign-keys typeorm typescript-decorator


【解决方案1】:

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

不,你不能。当你使用 @ManyToOne 装饰器时,TypeOrm 会自动创建外键属性。只需像这样将 @ManyToOne 和 @JoinColumn 装饰器组合在一起:

@ManyToOne(type => Category)
@JoinColumn({ name: 'custom_field_name_if_you_want' })
category: Category;

【讨论】:

    【解决方案2】:

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

        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);
    

    这段代码 sn-p 是从 orm 类型的functional test 中提取的,我认为您可以使用它在数据库上创建自己的约束。

    【讨论】:

      【解决方案3】:

      其实是可以的:

      @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;
      
      }
      

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

       post.categoryId = 1;
       // or 
       const id = post.categoryId
      

      【讨论】:

        【解决方案4】:

        检查这两个地方 Auth module(JwtModule.register()) 和 JWT strategy(super({...}))。确保您将秘密 /secretOrKey 设置为相同的密钥。就我而言,“secret:process.env.JWT_SECRET_KEY”和“secretOrKey:process.env.JWT_SECRET_KEY”

        【讨论】:

        • 嗨@Sunny Tare,记得使用块代码格式让你的代码在你的答案中更容易阅读
        【解决方案5】:

        我最近遇到了同样的问题。 我仍然使用实体,但仅使用引用实体的主键值。

        即我不查询被引用实体的数据库。

        假设您的类别实体如下所示:

        @Entity()
        export class Category{
            @PrimaryGeneratedColumn()
            id: number;
        
            // ... other stuff
        }
        

        现在以您的代码为例。 使用外键值直接分配关系就像。

        // You wish to assign category #12 to a certain post
        post.category = { id: 12 } as Category
        

        【讨论】:

          猜你喜欢
          • 2014-01-07
          • 2014-11-26
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2018-12-27
          • 2022-07-07
          • 1970-01-01
          相关资源
          最近更新 更多