TypeORM查询deletedAt非空条目时生成矛盾SQL条件的技术问题咨询
问题排查:TypeORM生成矛盾的deletedAt WHERE条件
嘿,这个问题我太熟悉了!你遇到的矛盾WHERE条件,根源在于TypeORM的软删除自动过滤机制。
为什么会出现这种情况?
你的Results实体应该是用了@DeleteDateColumn()装饰器来标记deletedAt字段,开启了软删除功能。TypeORM的软删除逻辑默认会给所有针对该实体的查询自动加上deletedAt IS NULL的过滤条件,确保默认只返回未被软删除的条目。而你手动添加了results.deletedAt IS NOT NULL的条件,这就和框架自动注入的条件撞在了一起,最终生成了互相矛盾的WHERE子句。
解决方法
方法1:临时关闭当前查询的软删除过滤
如果你只是想在这一次查询中获取已软删除的条目,只需要在QueryBuilder里加上withDeleted()方法,告诉TypeORM不要自动添加默认的软删除过滤:
const query = Results.createQueryBuilder('results') .withDeleted() // 关键:禁用本次查询的默认软删除过滤 .where('results.deletedAt IS NOT NULL') .skip(page * limit) .take(limit); console.log(query.getQuery()); return query.getManyAndCount();
修改后生成的SQL就只会保留你需要的results.deletedAt IS NOT NULL条件,不会再出现冲突的IS NULL了。
方法2:用Repository的API简化查询(可选)
如果你不是必须用QueryBuilder,也可以直接用Repository的查询方法,同样加上withDeleted选项:
const [results, count] = await resultsRepository.findAndCount({ withDeleted: true, where: { deletedAt: Not(null) }, skip: page * limit, take: limit, });
注意:全局修改需谨慎
如果你的业务逻辑需要默认返回所有条目(包括已软删除的),可以在实体的@Entity()装饰器里设置softDelete: false,但这会影响所有针对该实体的查询,除非你确定业务需求如此,否则不推荐这么做。
验证结果
调整后的代码生成的SQL应该会变成这样,完全符合你的预期:
SELECT "results"."id" AS "results_id", "results"."date" AS "results_date", "results"."shift" AS "results_shift", "results"."result" AS "results_result", "results"."createdAt" AS "results_createdAt", "results"."updatedAt" AS "results_updatedAt", "results"."deletedAt" AS "results_deletedAt" FROM "results" "results" WHERE "results"."deletedAt" IS NOT NULL LIMIT 10
内容的提问来源于stack exchange,提问作者Mohit.B
相关产品推荐
相关产品推荐

