如何在 TypeORM 中使用 SELECT 值插入

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

假设我有主表 Users 和参考表 UserRoles,这样每个用户都有一个角色保存在 roleId 列中,每个角色都有一个 id 和一个描述。

如果我想插入一个具有管理员角色的新用户,则可以使用以下 SQL 查询:

INSERT INTO `users` (`name`, `roleId`) 
VALUES ('John Doe', (SELECT `id` FROM `roles` WHERE `roles`.`description` = 'admin'));

如何在具有两个实体用户和角色的 TypeORM 中复制相同的内容?

我知道我可以做到以下几点:

const adminRole = await Role.findOne({description: 'admin'});
const newUser = User.create({name: 'John Doe'});
newUser.role = adminRole;
await newUser.save();

但这相当于将角色选择到变量中,然后在插入期间使用该变量。有没有一种方法可以将其压缩为一个查询,以便数据库仅被命中一次?

我知道我可以创建一个具有这样关系的用户

User.create({name: 'John Doe', role: {id: 1}});

但我需要知道这个的 id。如果我把名字写成下面这样

User.create({name: 'John Doe', role: {name: 'admin'}});

我收到以下错误

Error: Cannot find alias for relation at type
,因为我尚未加载关系。

我在这里找到了有关如何制作 INSERT INTO SELECT 语句的信息,但这是整个插入来自选择的地方,而不仅仅是特定列。

有没有办法模拟这个插入查询?或者我被迫分两步完成(或尽可能多的参考列)或使用查询生成器?

提前谢谢你

node.js typeorm
1个回答
0
投票

TypeOrm 不允许开箱即用,但是您可以通过两种方式实现这一点

1.使用查询生成器

const role = await getConnection()
        .createQueryBuilder()
        .select('role')
        .from(Role, 'role')
        .where('role.description = :description', { description: 'admin' })
        .getOne();

    if (!role) {
        console.error('Role not found');
        return;
    }

    const newUser = User.create({ name: 'John Doe', role });

2.使用交易

这种方法将保持原子性完整,并且一次性执行完整的操作(实际上可能看起来我们多次访问数据库,但在 typeorm 的底层将它们编译为要执行的单个查询)

import { getManager, getRepository } from 'typeorm';
import { User } from './entity/User';
import { Role } from './entity/Role';

async function createUserWithRole() {
    const entityManager = getManager();
    const roleRepository = getRepository(Role);

    try {
        await entityManager.transaction(async transactionalEntityManager => {
            const adminRole = await roleRepository.findOneOrFail({ description: 'admin' });
            const newUser = transactionalEntityManager.create(User, { name: 'John Doe', role: adminRole });
            await transactionalEntityManager.save(newUser);
        });
        console.log('User created successfully with role.');
    } catch (error) {
        console.error('Error creating user with role:', error);
    }
}

createUserWithRole();
© www.soinside.com 2019 - 2024. All rights reserved.