所以我正在使用 Nest js 创建后端服务 我正在遵循 dto 模式 现在我创建了一个像这样的产品 dto:
import { OmitType } from "@nestjs/mapped-types";
import { Product } from "../entities/product.entity";
import {AutoMap} from '@automapper/classes'
import { ApiProperty } from "@nestjs/swagger";
export class CreateProductDto{
@AutoMap()
@ApiProperty()
productId: string;
@AutoMap()
@ApiProperty()
productName: string;
@AutoMap()
@ApiProperty()
price: number;
@AutoMap()
@ApiProperty()
userId: string;
}
和这样的实体:
import { v4 as uuid } from 'uuid';
import { BaseEntity, Column, Double, Entity, PrimaryGeneratedColumn } from "typeorm";
import { AutoMap } from "@automapper/classes";
@Entity()
export class Product {
@AutoMap()
@PrimaryGeneratedColumn()
productId: number;
@AutoMap()
@Column({ type: 'varchar' })
productName: string
;
@AutoMap()
@Column({ type: 'float' })
price: number;
@AutoMap()
@Column({ type: 'uuid' })
userId: string;
}
然后创建一个像这样的自动映射器配置文件:
import { Injectable } from "@nestjs/common";
import { AutomapperProfile, InjectMapper } from "@automapper/nestjs";
import { Mapper, createMap, createMapper, forMember, ignore } from "@automapper/core";
import { CreateProductDto } from "./create-product.dto";
import { Product } from "../entities/product.entity";
import { UpdateProductDto } from "./update-product.dto";
@Injectable()
export class ProductMapper extends AutomapperProfile{
constructor(
@((InjectMapper as any)()) mapper: Mapper
){
super(mapper);
}
override get profile(){
return (mapper: Mapper) => {
createMap(mapper, CreateProductDto, Product, forMember(dest => dest.productId, ignore()))
createMap(mapper, UpdateProductDto, Product)
createMap(mapper, Product, CreateProductDto )
createMap(mapper, UpdateProductDto, Product)
createMap(mapper, Product, UpdateProductDto)
}
}
}
并在服务中使用它并且工作得很好,
现在我有另一个 DTO 需要更新,如下所示,我使用了 swagger 库中的映射类型:
import { PartialType } from '@nestjs/mapped-types';
import { CreateProductDto } from './create-product.dto';
export class UpdateProductDto extends PartialType(CreateProductDto) {}
但是这个 deos 不起作用,它无法执行映射......有什么想法吗? 谢谢。
问题是,当您使用 PartialType 时,它不会自动将 @AutoMap 装饰添加到 AutoMapper 所需的字段中。要解决此问题,请创建一个名为 custom-field-partial-type.ts 的新文件,并从以下链接复制代码:https://gist.github.com/Copystrike/bfc5010100aba362002616f9eca7fa25
代码的作用很简单:它允许您在使用 applyFields 函数时添加自定义装饰器。这意味着您可以添加 @AutoMap 装饰器,这对于映射很重要。
现在,您可以执行以下操作:
@InputType('UpdateTodoItemInput')
export class UpdateTodoItemInput extends CustomFieldPartialType(CreateTodoItemInput, {
customFields(partialObjectType, item) {
AutoMap()(partialObjectType.prototype, item.name); // This adds the AutoMap annotation to the field.
},
}) {}
或者你甚至可以变得更复杂一点:
@InputType('UpdateTodoItemInput')
export class UpdateTodoItemInput extends CustomFieldPartialType(CreateTodoItemInput, {
customFields(partialObjectType, item) {
if (item.name === 'text') {
AutoMap()(partialObjectType.prototype, item.name);
}
},
}) {}
此代码仅将 @AutoMap 装饰器添加到“文本”字段。
我已经在 GitHub 上的 @nestjs/graphql 存储库上提出了一个问题,也许有人能够将其集成到实际的库中。 这是问题的链接:https://github.com/nestjs/graphql/issues/3201