在 NestJS 中以多对一关系添加字段

Posted

技术标签:

【中文标题】在 NestJS 中以多对一关系添加字段【英文标题】:Add a field in a many-to-one relation in NestJS 【发布时间】:2020-08-15 08:50:53 【问题描述】:

我正在尝试开发一个小型应用程序来记录烹饪食谱。为此,我用 nestJS 声明了 2 个实体,允许我管理食谱和另一个来管理成分。我还创建了第三个实体来记录所需成分的数量:

Database diagram

// recipe.entity.js
@Entity()
export class Recipe 

  @PrimaryGeneratedColumn()
  id: number

  @Column('datetime')
  createdAt: Date

  @Column('datetime')
  updatedAt: Date

  @Column('varchar',  length: 100 )
  title: string;

  @Column('varchar', nullable: true)
  image: string;

  @OneToMany(type => RecipeIngredients, recipeIngredients => recipeIngredients.recipe)
  ingredients: RecipeIngredients[];

// ingredient.entity.js
@Entity()
export class Ingredient 

  @PrimaryGeneratedColumn()
  id: number

  @Column('datetime')
  createdAt: Date

  @Column('datetime')
  updatedAt: Date

  @Column('varchar',  length: 100 )
  name: string;

  @Column('varchar', nullable: true)
  image: string;

  @OneToMany(type => RecipeIngredients, recipeIngredients => recipeIngredients.ingredient)
  recipes: RecipeIngredients[];

// recipe_ingredients.entity.js
@Entity()
export class RecipeIngredients 

  @PrimaryGeneratedColumn()
  id: number

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

  @ManyToOne(type => Ingredient)
  ingredient: Ingredient

  @Column()
  quantity: string;

首先,我希望能够检索包含必要成分列表的食谱:

const recipe = await this.recipesRepository.createQueryBuilder('recipe')
    .where('recipe.id = :recipeId', recipeId: _id)
    .leftJoin('recipe.ingredients', 'recipe_ingredients')
    .leftJoin('recipe_ingredients.ingredient', 'ingredient')
    .getMany();

但是这个方法只返回我的食谱对象,没有成分...

[
  
    "id": 1,
    "createdAt": "2020-04-30T09:12:22.000Z",
    "updatedAt": "2020-04-30T09:12:22.000Z",
    "title": "Test",
    "image": null
  
]

从那里,我迷路了...如何直接从我的服务中获取我的成分列表(至少是名称和数量字段)?

提前感谢您的帮助。

【问题讨论】:

【参考方案1】:

使用leftJoin 可以让您在不选择数据的情况下加入数据。如果它有成分,它会选择配方,但不会返回它的成分。 如 TypeORM 文档中所述:

您可以在不选择数据的情况下加入数据。为此,请使用leftJoininnerJoin:

const user = await createQueryBuilder("user")
    .innerJoin("user.photos", "photo")
    .where("user.name = :name",  name: "Timber" )
    .getOne();

这将生成:

 SELECT user.* FROM users user
    INNER JOIN photos photo ON photo.user = user.id
    WHERE user.name = 'Timber'

如果他有照片,这将选择 Timber,但不会返回他的照片。

要选择成分,请尝试改用leftJoinAndSelect

【讨论】:

非常感谢,您的解决方案解决了我的问题,让我更好地理解!

以上是关于在 NestJS 中以多对一关系添加字段的主要内容,如果未能解决你的问题,请参考以下文章

flask 定义数据关系(多对一)

MyBatis之多对一关系

Hibernate 多对一关联查询

Hibernate中一对多和多对一关系

休眠:多对一关系失败

django--ORM表的多对一关系