TypeORM:@JoinTable有三列

问题描述 投票:2回答:1

我有一个关于typeorm和@ JoinTable-和@ RelationId-Decorator的问题。也许任何人都可以帮助回答我的问题,给我一个提示或理想地解决我的问题。

我正在使用带有typeorm的nestjs为我的家人和我提供私人api食谱。

如果我将数据库结构分解到最小,我们有三个主要实体:

recipe
- id INT(11)
- name VARCHAR(255)
# PRIMARY KEY is id

ingredient
- id INT(11) // not autoincrement, fetched from https://www.programmableweb.com/api/chomp
- name VARCHAR(255)
- recipeId INT(11)
# PRIMARY KEY is a composite key (id, recipeId) 
# FOREIGN KEY is recipeId on recipe

step
- id INT(11)
- name VARCHAR(255)
- recipeId INT(11)
# PRIMARY KEY is id
# FOREIGN KEY is recipeId on recipe

所以,这些是我食谱的三个主要实体。食谱可以有多个步骤(多步骤到一个食谱),食谱可以有多种成分(多种成分对一个食谱)

现在复杂的部分。每个步骤可以与一种或多种成分有关。这导致以下关系表。

ingredient_steps_step
- ingredientId INT(11)
- stepId INT(11)
- recipeId INT(11)
# PRIMARY KEY is a composite key (ingredientId, stepId, recipeId)
# FOREIGN KEYS are ingredientId on ingredient, stepId on step, recipeId on recipe

我的ingredient.entity.ts看起来像这样:

@ManyToMany(type => Step, step => step.ingredients)
@JoinTable({
  name: 'ingredient_steps_step',
  joinColumns: [
    {name: 'ingredientId'},
    {name: 'recipeId'},
  ],
  inverseJoinColumns: [
    {name: 'stepId'},
  ],
})
steps: Step[];

@RelationId((ingredient: Ingredient) => ingredient.steps)
stepIds: number[];

@PrimaryColumn()
recipeId: number;

@PrimaryColumn()
id: number;

@ManyToOne(type => Recipe, recipe => recipe.ingredients)
recipe: Recipe;  

问题是,我的成分表被填满了,但是关系表(ingredient_steps_step)没有填满条目。问题是,没有像@RelationIds这样的装饰器,我可以为实体步骤的关系提供两列。

如果你们中的任何人能够帮助我,那将是很棒的。也许有必要为您提供有关其他实体的更多信息?

亲切的问候,

数字黑客

sql typescript composite-primary-key nestjs typeorm
1个回答
0
投票

每个关系都应该在自己的表中。如果您在一个表中表示两个关系,您将创建重复并最终可能会出现不一致。

Example

让我们假设您有一个食谱MyRecipe,其中一步Step1有两个成分。现在,您要将Step1移动到另一个配方OtherRecipe。因为关系MyRecipe <-> Step1表示两次(重复),您必须更改多个条目。如果你忘了一个,你最终会得到损坏的数据。

ingredient_steps_step:
MyRecipe <-> Step1 <-> IngredientA
MyRecipe <-> Step1 <-> IngredientB

我会将数据建模如下:

steps:
Step1 -> MyRecipe

step_ingredients:
Step1 <-> IngredientA
Step1 <-> IngredientB

这样,您就没有重复。我假设食谱的成分是所有步骤成分的结合。

© www.soinside.com 2019 - 2024. All rights reserved.