Я новичок в NestJS, и мне было интересно, как лучше всего преобразовать DTO в сущность, когда атрибуты DTO не совпадают 1:1 с атрибутами сущностей.
Например, у меня есть следующие определения сущностей:
@Entity()
export class Category {
@PrimaryGeneratedColumn()
id: number
@Column()
name: string
@OneToMany(() => questionToCategory, questionToCategory => questionToCategory.category)
public questionToCategories: QuestionToCategory[];
}
export class Question {
@PrimaryGeneratedColumn()
id: number
@Column()
title: string
@Column()
text: string
@OneToMany(() => QuestionToCategory, questionToCategory => questionToCategory.question)
public questionToCategories: QuestionToCategory[];
}
export class QuestionToCategory {
@PrimaryGeneratedColumn()
public questionToCategoryId: number
@Column()
public questionId: number
@Column()
public categoryId: number
@Column()
public order: number
@ManyToOne(() => Question, (question) => question.questionToCategories)
public question: Question
@ManyToOne(() => Category, (category) => category.questionToCategories)
public category: Category
}
с этими определениями сущностей между вопросом и категориями существует связь «многие ко многим».
чтобы сохранить отношение «многие ко многим» из объекта вопроса, вы можете сделать что-то вроде этого:
questionToCategories: { categoryId: "some_id_value" }
это работает нормально, однако моя структура DTO не полностью соответствует этой структуре.
если мой вопрос dto выглядит примерно так:
export class CreateQuestionDto {
@IsString()
title?: string;
@IsString()
title?: string;
@IsOptional()
@IsArray()
bundles: string[];
}
где Bundles — это массив идентификаторов, соответствующих категории. Я не могу напрямую сохранить этот DTO как объект, так как поле Bundles не совпадает с вопросомToCategories. Есть ли в NestJS какая-либо передовая практика для преобразования dto в эквивалентное представление объекта?





Я предполагаю, что ваш DTO не может быть изменен и сопоставлен в соответствии с объектами. В этом случае вы не сможете сохранить напрямую посредством приведения, и это не сможет выполнить каскадную вставку. Что вы можете сделать, так это создать службу картографирования, которая сначала сохранит вопросы, получит их идентификаторы, а затем сопоставит их с вашей сущностью QuestionToCategory, а затем сохранит их:
import { Injectable } from '@nestjs/common';
import { InjectRepository } from '@nestjs/typeorm';
import { Repository } from 'typeorm';
import { CreateQuestionDto } from './dto/create-question.dto';
import { Question } from './entities/question.entity';
import { Category } from './entities/category.entity';
import { QuestionToCategory } from './entities/question-to-category.entity';
@Injectable()
export class QuestionService {
constructor(
@InjectRepository(Question)
private questionRepository: Repository<Question>,
@InjectRepository(Category)
private categoryRepository: Repository<Category>,
@InjectRepository(QuestionToCategory)
private questionToCategoryRepository: Repository<QuestionToCategory>,
) {}
async create(createQuestionDto: CreateQuestionDto): Promise<Question> {
const { title, text, bundles } = createQuestionDto;
const question = new Question();
question.title = title;
question.text = text;
const savedQuestion = await this.questionRepository.save(question);
const questionToCategories: QuestionToCategory[] = [];
for (const categoryId of bundles) {
const category = await this.categoryRepository.findOne(categoryId);
if (category) {
const questionToCategory = new QuestionToCategory();
questionToCategory.question = savedQuestion;
questionToCategory.category = category;
questionToCategories.push(questionToCategory);
}
}
await this.questionToCategoryRepository.save(questionToCategories);
return this.questionRepository.findOne(savedQuestion.id, { relations: ['questionToCategories'] });
}
}
В классе обслуживания вы можете внедрять репозитории ваших объектов и использовать их для соответствующего получения и сохранения в ваших таблицах.