You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 20:07:33