TypeORM保存嵌套对象

2024-01-15

我正在开发一个express(使用TypeORM)+ ReactJS应用程序。

问题是我有 3 个通过 OneToMany 关系链接的实体,如下所示:

  1. customer
  2. 产品(链接到客户)
  3. 型号(与产品相关)
import { Product } from './product.entity'

@Entity('customer')
export class Customer extends BaseEntity{
    @PrimaryGeneratedColumn()
    readonly id: number;
   
    @Column ({name: 'name'})
    name : string;

    @Column ({name: 'test', nullable: true})
    test : string;

    @OneToMany(() => Product, product => product.customer)
    // @JoinColumn({ name: 'product_id' })
    products: Product[]
}
import {Customer} from './customer.entity'
import {Model} from './model.entity'

@Entity('product')
export class Product extends BaseEntity{
    @PrimaryGeneratedColumn()
    readonly id: number;
   
    @Column ({name: 'name'})
    name : string;

    @Column ({name: 'test', nullable: true})
    test : string;

    @Column ({name: 'deleted', nullable: true})
    deleted : string;
    
    @ManyToOne(() => Customer, customer => customer.products)
    @JoinColumn({ name: 'customer_id' })
    customer: Customer;

    @OneToMany(() => Model, model => model.product)
    @JoinColumn({ name: 'customer_id' })
    models: Model[]
}
import { Product } from "./product.entity";

@Entity('model')
export class Model extends BaseEntity{
    @PrimaryGeneratedColumn()
    readonly id: number;
   
    @Column ({name: 'name'})
    name : string;

    @Column ({name: 'size', nullable: true})
    size : string;

    @Column ({name: 'deleted', nullable: true})
    deleted : string;
    
    @ManyToOne(() => Product, product => product.models)
    @JoinColumn({ name: 'product_id' })
    product: Product;
}

Express的保存方法是:

  static add = async(req: Request, res)=> {
    const connection = getConnection();
    const queryRunner = connection.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();
    try {
      let customer: Customer
      customer = await queryRunner.manager.getRepository(Customer).findOneOrFail(req.body.id)

      const productsReq: Array<Product> = req.body.products
      productsReq.forEach(async (product: any) => {
        let updatedProd =  {...product, customer: customer}
        const savedProd = await queryRunner.manager.getRepository(Product).save({...updatedProd})
        product.models.forEach(async (model: any) => {
          let updatedModel = {...model, product: savedProd}
          await queryRunner.manager.getRepository(Model).save(updatedModel)
        });
      });

      await queryRunner.commitTransaction();
      return res.send('Saving done')

    } catch (error) {
      console.log(error)
      await queryRunner.rollbackTransaction();
      res.status(500).send('Some error occurs');
    } finally {
    }
  }

目前,在数据库中,我有以下数据:

1 位 ID 为 30 的客户

name id test
first customer 30 test column

1 个 ID 为 119 的产品关联到客户 30

id name test customer_id deleted
119 first product test column 30

2 个型号,其 ID:90 和 91 链接到产品 119

id name size deleted product_id
91 second model witout id 2000 119
90 first model with id 1000 119

接下来,在 React 中,我尝试仅更新 id 为 90 的模型并添加一个新模型。 (所以我不会发送到后端所有模型,id 为 91 的模型不会发送)。

从前端发送到后端的 JSON 对象如下所示:

{
    "id": 30,
    "name": "first customer",
    "test": "test column",
    "products": [
        {
            "id" : 119,   
            "name": "first product",
            "test": "test column",
            "models": [
                {
                    "id": 90,
                    "name": "first model with id",
                    "size": 1000
                },
                {
                    "name": "second model witout id",
                    "size": 2000
                }
            ]
        }

    ]
}

但问题是在数据库中,对于 id 为 91 的模型,表“model”上的外键“product_id”设置为 null,并插入了新行(92)。

结果是:

|id|name|size|deleted|product_id|
|--|----|----|-------|----------|
|91|second model witout id|2000|||
|90|first model with id|1000||119|
|92|second model witout id|2000||119|

如何添加新模型并更新现有模型而不发送数据库中的所有现有模型?


我想我找到了解决方案。

我从 Express 更改了保存方法,如下所示:

  static add = async(req: Request, res)=> {
    const connection = getConnection();
    const queryRunner = connection.createQueryRunner();
    await queryRunner.connect();
    await queryRunner.startTransaction();
    try {
      let customer: Customer
      let customerReq: any = req.body
      customer = await queryRunner.manager.getRepository(Customer).findOneOrFail(req.body.id)
      const productsReq: Array<Product> = req.body.products
      
      productsReq.forEach(async (product: any) => {
        let updatedProd =  {...product, customer: customer}
        let addedModels: Model[] = []
        product.models.forEach(async (model: any) => {
          const updatedModel = await queryRunner.manager.getRepository(Model).save({...model, product: product})
          addedModels.push(updatedModel)
        });
        const existingProd = await queryRunner.manager.getRepository(Product).save({...updatedProd})
        await (await existingProd.models).push(...addedModels)
        const savedProd = await queryRunner.manager.getRepository(Product).save({...updatedProd})
      });

      await queryRunner.commitTransaction();
      return res.send('Adding ok')

    } catch (error) {
      console.log(error)
      await queryRunner.rollbackTransaction();
      res.status(500).send('Something went terribly wrong');
    } finally {
      console.log('release')
      // await queryRunner.release();
    }
  }

这很奇怪,因为有 2 个事务启动了:

query: START TRANSACTION
query: SELECT "Customer"."id" AS "Customer_id", "Customer"."name" AS "Customer_name", "Customer"."test" AS "Customer_test" FROM "customer" "Customer" WHERE "Customer"."id" IN ($1) -- PARAMETERS: [30]
query: SELECT "Customer"."id" AS "Customer_id", "Customer"."name" AS "Customer_name", "Customer"."test" AS "Customer_test" FROM "customer" "Customer" WHERE "Customer"."id" IN ($1) -- PARAMETERS: [30]
query: COMMIT
query: SELECT "Model"."id" AS "Model_id", "Model"."name" AS "Model_name", "Model"."size" AS "Model_size", "Model"."deleted" AS "Model_deleted", "Model"."product_id" AS "Model_product_id" FROM "model" "Model" WHERE "Model"."id" IN ($1) -- PARAMETERS: [132]
query: SELECT "Product"."id" AS "Product_id", "Product"."name" AS "Product_name", "Product"."test" AS "Product_test", "Product"."deleted" AS "Product_deleted", "Product"."customer_id" AS "Product_customer_id" FROM "product" "Product" WHERE "Product"."id" IN ($1) -- PARAMETERS: [119]
query: INSERT INTO "model"("name", "size", "deleted", "product_id") VALUES ($1, $2, DEFAULT, $3) RETURNING "id" -- PARAMETERS: ["second model witout id",2000,119]
release

 Morgan -->  POST 200 /test @ Tue, 04 May 2021 14:28:08 GMT ::ffff:127.0.0.1 from undefined PostmanRuntime/7.28.0

query: START TRANSACTION
query: SELECT "Product"."id" AS "Product_id", "Product"."name" AS "Product_name", "Product"."test" AS "Product_test", "Product"."deleted" AS "Product_deleted", "Product"."customer_id" AS "Product_customer_id" FROM "product" "Product" WHERE "Product"."id" IN ($1) -- PARAMETERS: [119]
query: UPDATE "model" SET "size" = $2 WHERE "id" IN ($1) -- PARAMETERS: [132,8000]
query: COMMIT
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

TypeORM保存嵌套对象 的相关文章

随机推荐

  • Android:当url包含http时,在设置WebViewCore之前不支持removeMessages(int What = 107)

    我编写了一个简单的程序 它将网页加载到网络视图中 URL 包含 http 并且 Web 视图工作得很好 除了这个恼人的 107 错误之外 大多数人说这是因为你的 url 不包含 http 标头 我在网上搜索了所有内容 但找不到与我的情况类似
  • 如何显示完整的数组?

    我得到这个error 对象对象 对象对象 对象对象 我想像这样显示完整的数组 无名氏 安娜 史密斯 彼得 琼斯 h2 Create Object from JSON String h2 p p
  • 如何从函数返回 &Path?

    我试图了解如何编写正确的 Rust 代码 但我认为我可能高估了编译器理解对象生命周期的能力 这是我期望它工作的代码 use std path Path use std env use rusqlite SqliteConnection st
  • Vlookup复制单元格的颜色

    我有以下表格 A B C D 1 Bob 1 6 Football 2 Nate 3 7 Baseball 3 Silver 3 2 Baseball 4 Box 7 1 Cycling A D Bob Nate 我可以成功使用Vlooku
  • “TypeError:‘StratifiedShuffleSplit’对象不可迭代”的原因可能是什么?

    我必须交付一个机器学习项目 我收到了一个名为tester py 在另一个文件中编写完代码后 我必须运行 tester py 才能查看结果 但出现错误 TypeError StratifiedShuffleSplit object is no
  • mysql 选择内部限制

    select id from tableABC limit select count id from tableCBA 1 如果我需要在限制中进行选择 如我在示例代码中所示 我该如何在 mySql 中执行此操作 这只是本论坛的简化代码 否则
  • 设置 MaxTextWidth 时出现 WPF 字对齐问题

    我正在使用 FormattedText 来显示文本 我需要根据提供的选项水平对齐文本 一切正常 直到我设置 MaxTextWidth 属性 我需要它来进行文字修剪 如何在启用文字修剪的情况下对齐文本 FormattedText format
  • 我如何在 C# 中执行 sscanf

    我如何在 C 中执行此操作 int a b c sscanf astring d d d a b c 最少的代码和依赖项是更好的 是否有一些内置的正则表达式的东西 我正在使用 c 4 0 如果像 scannf 一样 您愿意假设用户将提供完全
  • 在 Xcode 中,如何在块内添加断点?

    我有一个返回块的方法 我想在块内添加一个断点 在 Xcode 中 在块内的行上添加断点会导致执行在方法返回时暂停 而不是在执行块时暂停 如何在块内添加断点 我遇到了同样的困难 直到我尝试使用 Xcode 4 的 LLDB 调试器 转到 产品
  • 如何在命令行中使用VLC保存视频流?

    我正在尝试在 Window 7 Basic 的命令行中使用 VLC 保存在线视频 以下是我尝试过并部分起作用的一些事情 I movies gt vlc http media ch9 ms ch9 7492 a92ae0a6 7b81 411
  • C 和 doxygen - 删除变量文档的重复项

    我正在使用 doxygen 记录我的 C 代码 为了更好的可读性 我将每个 c h 文件对 有时还有更多文件 的文档分组为defgroup and addtogroup see c 中的 doxygen 定义分组 https stackov
  • Actionscript 3可以在数组中设置对象的多个变量吗?

    现在我有很多MovieClips在我的数组中 我想更新所有alpha我的数组中 MovieClip 的值 现在 我正在使用 for 循环 但这不是最快的方法 有没有办法为数组中的所有项目设置值 Thanks No ActionScript没
  • 未捕获的类型错误:将 vue 升级到 3.x 后无法读取未定义的属性(读取“扩展”)

    今天我将我的 google chrome 扩展 vue 版本升级到 3 x 当运行该应用程序时 google chrome 扩展弹出控制台显示如下错误 commons1 js 13392 Uncaught TypeError Cannot
  • 在python中使用in运算符搜索列表时使用什么算法?

    当使用 in 运算符搜索列表中的项目时 例如 if item in list print item 使用什么算法来搜索该项目 是从头到尾直接搜索列表还是使用二分搜索之类的东西 list不能假定 s 是按排序顺序 或任何顺序 的 因此二分搜索
  • SHA256 哈希值总是有 64 个字符吗?

    我正在将数据库设置为接收散列密码而不接受纯文本 我会去这样的事情吗 create table User username varchar 20 not null password varchar 64 not null 是的 SHA256
  • 使用 Parcelable 是在应用程序之间发送数据的正确方法吗?

    我试图了解如何在 Android 中的应用程序之间进行通信 而不仅仅是在应用程序之间进行通信Activity实例 我设置了一个 客户端 将 Messenger 对象发送到服务 在Intent发送到服务 该服务创建了一个Messageobj
  • 调整 Dash-Plotly 中下拉菜单选项的宽度

    我正在尝试基于 Plotly 在 Python 中使用 Dash 构建一个应用程序 我很难调整下拉菜单选项的宽度 我在下面附上了代码和图像 我希望下拉选项的宽度与菜单宽度相同 app layout html Div children htm
  • 如何在适配器内的列表视图项内添加地图片段?

    我有一个列表视图 我想在每个列表项中添加地图 当我单击列表项时 地图将显示 隐藏 当地图显示时 我可以在其上缩放 查看位置详细信息 但我无法在适配器中设置 MapFragment 那么 给我一些解决方案 谢谢 gMap MapFragmen
  • 使用 R microbenchmark 和 system.time 有什么区别?

    我想了解 R 的 microbenchmark 和 system time 之间的区别 他们如何在内部测量函数执行时间 在这两种情况下 运行时间都是使用操作系统工具计算的 因此 如何计算运行时间取决于操作系统 如详细信息部分所述 syste
  • TypeORM保存嵌套对象

    我正在开发一个express 使用TypeORM ReactJS应用程序 问题是我有 3 个通过 OneToMany 关系链接的实体 如下所示 customer 产品 链接到客户 型号 与产品相关 import Product from p