自定义实体管理器,事务为typeform



因此,我们需要在带有typeform的事务函数下实现一个自定义实体管理器。为什么?因为我们从typeform中包装了实体管理器,并用一些我们需要的自定义函数来增强它。

@Injectable()
export class CustomEntityManager extends EntityManager implements IEntityManager {
constructor(connection?: string) {
super(getConnection(connection));
}
//#region CRUD methods
async createOne<Entity, Dto extends CreateDto>(
entity: EntityTarget<Entity>,
dto: Dto,
extraOptions?: ExtraOptions,
): Promise<Entity> {
try {
const _entity = this.create(entity, instanceToPlain(dto) as any);
return await this.save(entity, _entity);
} catch (err) {
const entityName = extraOptions?.entityName || startCase((entity as Function).name);
throw new CreateEntityException(entityName, err);
}
}
// a lot of more functions
customSoftDelete<Entity>(entity: EntityTarget<Entity>, criteria: any): Promise<UpdateResult> {
try {
return this.update(entity, criteria, { deleted: true } as any);
} catch (e) {
console.log(e);
// @todo: open this error and check
throw e;
}
}
customTransaction<Entity>(
runInTransaction: (entityManager: CustomEntityManager) => Promise<Entity>,
): Promise<Entity> {
return super.transaction(runInTransaction);
}
}

这就是我们的自定义实体管理器的样子。现在我们正在尝试使用它来软删除一些实体(在你说类型的软删除不像我们需要的那样工作之前)

async deleteOne(id: Id): Promise<void> {
const company = await this.findOneWithScopeOr404({ where: { id } });
await this.manager.customTransaction(async (transactionManager) => {
console.log(transactionManager);
this.logger.log('removing company users');
const userTransaction = await transactionManager.customSoftDelete(User, { companyId: company.id });
this.logger.log(userTransaction);
});
}

但是当这样做时,我认为customTransaction下的transactionManager是"自定义实体管理器"。但事实并非如此。在编译时没有错误,但在运行时它是…customSoftDelete不是entitymanager的函数。有办法修改吗?

这是一个可能的解决方案,让我知道它是否有效。

首先没有输入问题,因为你在这里声明了:

runInTransaction: (entityManager: CustomEntityManager) => Promise<Entity>,

但实际上,typeform Transaction具有以下签名:

async transaction<T>(
runInTransaction: (entityManager: EntityManager) => Promise<T>,
): Promise<T>

当你调用customTransaction方法时,你只是返回父行为,所以transactionManager是父(EntityManager)是正常的。

但是你可以通过使用函数绑定来绕过这个:

customTransaction<Entity>(
runInTransaction: (entityManager: CustomEntityManager) => Promise<Entity>,
): Promise<Entity> {
return super.transaction(runInTransaction.bind(null, this)); // this equals to an instance of CustomEntityManager
}

最新更新