【问题标题】:How to save ManyToMany relations in TypeOrm如何在 TypeOrm 中保存多对多关系
【发布时间】:2021-04-07 10:42:58
【问题描述】:

我有一个产品实体,如下所示:

@Entity('products')
export class productsEntity extends BaseEntity{
    @PrimaryGeneratedColumn()
    id: number;
    //...Unrealted Columns
    @Column({nullable: false, unique: true})
    title: string;

    @ManyToMany( type => categoryEntity, category => category.products, {cascade: true, eager: true})
    @JoinTable({name:"products_categories",
                joinColumn: {name: 'productName', referencedColumnName: 'title'},
                inverseJoinColumn: {name: 'categoryName', referencedColumnName:'title'}
              })
    categories: categoryEntity[];

    @Column({type:"text", nullable: false})
    soldBy: userEntity;
}

然后我还有一个类别实体:

@Entity('categories')
export class categoryEntity extends BaseEntity{
    @PrimaryGeneratedColumn()
    id: number;

    @Column({nullable: false, default: 'all', unique: true})
    title: string;
    

    @ManyToMany(()=> productsEntity, product => product.categories)
    products: productsEntity[];
}

由于它们具有多对多关系,因此我无法将任何内容保存到联结表中。此外,类别是预定义的,如果存在,则会在服务中进行检查。 我正在尝试这个存储库方法:

  async addProduct(productDetails, username, catTitle){
        const {title, description, belongsTo, price, units}  = productDetails;
        try{ 
            let newProduct = new productsEntity();
            newProduct.title = title;
            newProduct.description = description;
            newProduct.price = price;
            newProduct.units = units;
            newProduct.categories.push(catTitle);
            newProduct.soldBy = username;
            await this.manager.save(newProduct);
        }
        catch(err){
            this.logger.error(err.message);
            throw new HttpException('Failed adding Product.', HttpStatus.INTERNAL_SERVER_ERROR)
        }
    }
}

【问题讨论】:

    标签: javascript typescript typeorm


    【解决方案1】:

    假设您将catTitle 中的newProduct.categories 推送为基于标题和产品名称之间的关系,
    这就是您正在使用的数据库引擎(MySQL、Postgres...) 进行操作和处理的内容,但在 TypeOrm 中我们使用对象,
    如果你在关系中看到:

         @ManyToMany( type => categoryEntity, category => category.products, {cascade: true, eager: true})
        @JoinTable({name:"products_categories",
                    joinColumn: {name: 'productName', referencedColumnName: 'title'},
                    inverseJoinColumn: {name: 'categoryName', referencedColumnName:'title'}
                  })
        categories: categoryEntity[]; // you have a list of categories not a title 
    
    **So the solution is** to pass a category object, not just the title, to do that:
    
          async addProduct(productDetails, username, catTitle){
                const {title, description, belongsTo, price, units}  = productDetails;
                try{ 
            
                    let newProduct = new productsEntity();
                    newProduct.title = title;
                    newProduct.description = description;
                    newProduct.price = price;
                    newProduct.units = units;
                    const category= await this.CategoryRepository.findOne( { where: { title: catTitle } }); // get the category 
                      //try this approach 
      newProduct.categories = newProduct?.categories ?? []; 
      newProduct.categories.push(category);
                     // or add them from category 
        category.products= category?.products?? []; 
      category.products.push(products);
    await  category.save();
                    newProduct.soldBy = username;
                    await this.manager.save(newProduct);
                }
                catch(err){
                    this.logger.error(err.message);
                    throw new HttpException('Failed adding Product.', HttpStatus.INTERNAL_SERVER_ERROR)
                }
            }
        } 
    

    【讨论】:

    • 好的理解,但尝试这给了我“无法读取未定义的属性推送”。​​
    • Anwser 已更新 question.categories = [category];
    • @Youba 我猜这将不再是一个数组。它只会每次更改类别。我们应该看看为什么 push 方法不起作用?介意分享 git repo 吗??
    • @TusharRoy 我认为您应该阅读有关数组 Array declaration 的信息,我在这里没有使用 push 的原因是因为 question.categories 没有初始化,所以最干净的方法是使用一组类别(我们这里只有一个)
    猜你喜欢
    • 2021-10-18
    • 2021-05-11
    • 2021-04-23
    • 2019-04-24
    • 2020-06-29
    • 2020-10-15
    • 2014-11-21
    • 2021-08-09
    • 2020-08-29
    相关资源
    最近更新 更多