如何解决此 TypeORM 错误“EntityRepository 已弃用,请改用 Repository.extend 函数”?

Net*_*al. 25 typeorm nestjs

但是,我在 Repository 类中找不到任何 Repository.extend 方法,文档中也没有任何相关内容。怎么解决这个问题呢?

类型版本:“^0.3.0”

我正在使用 Nest js 并尝试创建自定义存储库。

Abo*_*zlR 17

首先:

npm install @nestjs/typeorm@next
Run Code Online (Sandbox Code Playgroud)

笔记

在我的项目中@nestjs/typeorm版本是9.0.0-next.2并且typeorm版本是0.3.6

在项目的 src 中创建一个名为database的文件夹,然后在(typeorm-ex.decorator.tstypeorm-ex.module.ts)中创建两个文件

// typeorm-ex.decorator.ts

import { SetMetadata } from "@nestjs/common";

export const TYPEORM_EX_CUSTOM_REPOSITORY = "TYPEORM_EX_CUSTOM_REPOSITORY";

export function CustomRepository(entity: Function): ClassDecorator {
  return SetMetadata(TYPEORM_EX_CUSTOM_REPOSITORY, entity);
}
Run Code Online (Sandbox Code Playgroud)

和下一个文件

// typeorm-ex.module.ts

import { DynamicModule, Provider } from "@nestjs/common";
import { getDataSourceToken } from "@nestjs/typeorm";
import { DataSource } from "typeorm";
import { TYPEORM_EX_CUSTOM_REPOSITORY } from "./typeorm-ex.decorator";

export class TypeOrmExModule {
  public static forCustomRepository<T extends new (...args: any[]) => any>(repositories: T[]): DynamicModule {
    const providers: Provider[] = [];

    for (const repository of repositories) {
      const entity = Reflect.getMetadata(TYPEORM_EX_CUSTOM_REPOSITORY, repository);

      if (!entity) {
        continue;
      }

      providers.push({
        inject: [getDataSourceToken()],
        provide: repository,
        useFactory: (dataSource: DataSource): typeof repository => {
          const baseRepository = dataSource.getRepository<any>(entity);
          return new repository(baseRepository.target, baseRepository.manager, baseRepository.queryRunner);
        },
      });
    }

    return {
      exports: providers,
      module: TypeOrmExModule,
      providers,
    };
  }
}
Run Code Online (Sandbox Code Playgroud)

打开您的 AppModule 并进行如下修改:

@Module({
  imports: [
    TypeOrmModule.forRoot({
      type: 'mssql',
      ...
      entities: [Photo],
    }),
    TypeOrmExModule.forCustomRepository([PhotoRepository]),
    ...
  ],
  controllers: [AppController],
  providers: [
    AppService
  ],
})
export class AppModule { }
Run Code Online (Sandbox Code Playgroud)

您可以像下面这样创建客户存储库:

@CustomRepository(Photo)
export class PhotoRepository extends Repository<Photo> {
    public async getAllPhoto() {
        const query = this.createQueryBuilder('photo')
            .where('photo.isPublished = :isPublished', { isPublished: true })
        const photos = await query.getMany()
        return photos
    }
}
Run Code Online (Sandbox Code Playgroud)

一切都很完美。

感谢 @anchan828


Žel*_*vić 13

使用当前版本的 TypeORM,可以利用 DataSource 通过以下方式实现自定义存储库。

// user.repository.ts
@Injectable()
export class UsersRepository extends Repository<UsersEntity> {
  constructor(private dataSource: DataSource) {
    super(UsersEntity, dataSource.createEntityManager());
  }

  async getById(id: string) {
    return this.findOne({ where: { id } });
  }
  // ...
}
Run Code Online (Sandbox Code Playgroud)

然后将存储库注入到服务中。

// user.service.ts
export class UserService {
  constructor(private readonly userRepository: UserRepository) {}

  async getById(id: string): Promise<User> {
    return this.userRepository.getById(id);
  }
  // ...
}
Run Code Online (Sandbox Code Playgroud)

并且该模块具有作为提供者的功能和存储库的导入。

// user.module.ts
@Module({
  imports: [
    TypeOrmModule.forFeature([UserEntity])],
    // ...
  ],
  providers: [UserService, UserRepository],
  // ...
})
export class UserModule {}
Run Code Online (Sandbox Code Playgroud)


小智 6

在新版本的 TypeORM (0.3.*) 中,我将自定义存储库更改为服务。基于连接多个官方文档数据库。 https://docs.nestjs.com/techniques/database#multiple-databases

自定义存储库

  @EntityRepository(Person)
  export class PersonRepository extends Repository<Person> {...}
Run Code Online (Sandbox Code Playgroud)

自定义存储库即服务

  @Injectable()
  export class PersonRepository {
    constructor(private dataSource: DataSource) { }

    exampleQueryBuilder() {
      return this.dataSource
          .getRepository(Person)
          .createQueryBuilder() ...
    }
Run Code Online (Sandbox Code Playgroud)

存储库注入

  @Injectable()
  export class PersonService {
    constructor(
      @Inject(PersonRepository)
      private readonly personRepository: PersonRepository,
    ) {}
Run Code Online (Sandbox Code Playgroud)