首页 > 解决方案 > 我如何使用 ManyToMany 关系更新某些实体

问题描述

请帮帮我。我真的不明白它是如何工作的,我有一个名为 Product 的实体,它与另一个名为 Car 的实体具有多对多关系,并启用了级联 true 标志。

@Entity()
export class Product {
  @PrimaryGeneratedColumn()
  id: number

  @ManyToMany(() => Car, { cascade: true })
  @JoinTable()
  cars: Car[]
}

Car 实体不包含对 Product 实体的引用。这意味着就像我认为这种关系是单向的。所以,当我保存一个产品时,我为这个产品设置了汽车:

const cars = await this.carService.getByIds(createProductDto.cars)

const newProduct = this.productsRepository.create({
    ...createProductDto,
    cars
})

await this.productsRepository.save(newProduct)

我通过 id 获取汽车实体并将它们保存到产品中。这很好用。我不确定这是最好的方法,但我不知道另一种方法。

当我尝试更新数据库中的一些现有产品时,问题就来了。我得到了休闲错误:

ERROR [ExceptionsHandler] duplicate key value violates unique constraint "PK_f7b49d8fd8d09ea2fc2e7542f3f"

或者

Error: Cannot query across many-to-many for property cars

或其他...请帮助我。我想了解处理这种关系的最佳方式是什么。创建、更新和删除它的最佳方法是什么。谢谢

标签: javascriptpostgresqlnestjstypeorm

解决方案


您声称在汽车和产品之间存在 M:M,但这不是您所描述的。您描述了汽车和产品的 1:M。在 Products 表中引用 Cars 意味着给定的 Car 可以有许多 Products,但给定的 Product 只能被 1 辆汽车使用。这是从 Products 中引用 Cars 的结果(我不会将其归类为单向,因为我可以得到另一个,它只是我可以得到更改的数字。)但是,我相信你想要一个 M:M。M:M 的典型实现需要第三张表。使用此配置,Cars 和 Products 表都不会引用另一个,而是第三个表同时引用两者。不幸的是,我不认识或不认识您的混淆管理器(您正在使用的 ORM)。因此,我将为这些表绘制一个可能的 ddl 定义。

create table cars ( car_id   integer generated always as identity primary key
                  , vin      text 
                  , manufacturer text
                  -- other Car attributes
                  );
                 
create table products( prod_id integer generated always as identity primary key
                     , manufacturer text 
                     -- other product 
                     ); 
                     
-- create the reference/intersection table for M:M Cars:Products
create table car_products( car_id    
                         , prod_id   
                         -- attributes that pertain only to the combination of 
                         -- of the other tables 
                         , model_code text 
                         , serial_number text
                         -- constraints  
                         , constraint car_products_pk
                                      primary key (car_id, prod_id)
                         , constraint car_products_2_cars_fk
                                      foreign key (car_id) 
                                      references cars(car_id) 
                                      on delete cascade
                         , constatint car_products_2_products_fk
                                      foreign key(prod_id)
                                      references products(prod_id) 
                                      on delete cascade                                      
                         ); 

现在通过这种设置,给定的汽车可以拥有任意数量的产品,并且给定的产品可以被任意数量的汽车使用。(注意:在此设置中,产品与零件不同。)我希望这可以帮助您理解 1:M 关系与 M:M 关系。


推荐阅读