TypeORM:将不相关的实体映射到数组属性中



我有以下不相关的TypeORM实体(由于各种原因,我不能在它们上使用一个或多个关系(:

@Entity()
export class Book {
@PrimaryGeneratedColumn()
id: number;
@Column()
name: string;
}
@Entity()
export class BookCategory {
@PrimaryGeneratedColumn()
id: number;
@Column()
bookId: number;
@Column()
name: string;
}

使用一本书、两个分配的类别和以下查询:

const query = this.bookRepository
.createQueryBuilder('book')
.leftJoinAndSelect(BookCategory, 'category', 'book.id = category.bookId');
return query.execute();

我得到以下响应:

[
{
"book_id": 1,
"book_name": "Lorem Ipsum",
"category_id": 1,
"category_name": "non-fiction"
},
{
"book_id": 1,
"book_name": "Lorem Ipsum",
"category_id": 2,
"category_name": "documentary"
}
]

如您所见,我得到了 2 个对象。有什么方法可以通过TypeORM查询获得以下内容吗?

[
{
"id": 1,
"name": "Lorem Ipsum",
"categories": ["non-fiction", "documentary"]
}
]

即我正在尝试将查询结果绑定到虚拟属性categories。这可能吗?

我认为TypeORM本身不可能做到这一点,但是您可以使用map()函数通过以下方式实现它:

const categories: string[] = query.execute().map((book) => book.category_name );
const book = {id: bookArray[0].book_id, name: bookArray[0].book_name, categories};
//OUTPUT: 
{
id: 1,
name: 'Lorem Ipsum',
categories: [ 'non-fiction', 'documentary' ]
}

这不是一种干净的方法,但是由于您通过其ID请求单个书籍,因此您将确保每个数组对象中的book_idbook_name属性始终相同。

TypeORM 还建议使用getMany()getOne()而不是执行查询:

const books: Book[] = await this.bookRepository
.createQueryBuilder('book')
.leftJoinAndSelect(BookCategory, 'category', 'book.id = category.bookId')
.getMany();

我不知道他怎么做queryBuildersql它看起来像这样。

SELECT
book.id as book_id,
book.name as book_name,
array_remove(array_agg(bc.name), NULL) as categories
FROM book
LEFT JOIN book_category bc ON bc."bookId"=book.id
GROUP BY book.id

我可能犯了一个错误,因为我没有自己检查它。但它应该是这样的。

执行时,你应该得到一个表

12 书名
book_idbook_namecategory
本书名称1["猫名", "猫名2"]
2["猫名"]

最新更新