如何在 TypeORM 查找选项中设置 IS NULL 条件?

How can I have IS NULL condition in TypeORM find options?

在我的查询中,我使用了 TypeORM find 选项。 如何在 where 子句中包含 IS NULL 条件?

您可以将 QueryBuilder 用于此目的:

const users = await userRepository.createQueryBuilder("user")
     .where("user.name IS NULL")
     .getMany();

另一种方法是使用IsNull()函数,例如:

import { IsNull } from "typeorm";
return await getRepository(User).findOne({
    where: { 
      username: IsNull()
    }
});

除了 hungneox answer 你应该知道你有很多预定义的运算符。

这来自定义它的文件:

export declare type FindOperatorType = "not" | 
"lessThan" | 
"lessThanOrEqual" | 
"moreThan" | 
"moreThanOrEqual" | 
"equal" | 
"between" | 
"in" | 
"any" | 
"isNull" | 
"like" | 
"raw";

以上每一项都可以在此处的"Operator"部分进行设置:

{ 
  where: { 
    propertyToCheck: <Operator>
  }
}

您只需从@typeorm 包中导入它并像函数一样使用它,例如 LessThan():

import { Repository, Between, IsNull, LessThan } from 'typeorm';

{ 
  where: { 
    age: LessThan(50)
  }
}

如果你想掌握 typeorm,这是一个非常强大和重要的工具:) 祝你好运!

我真的不喜欢为此使用 TypeORM 中的 QueryBuilder,因为在我看来,在使用 FindConditions.

时应该按预期对待它

不幸的是,使用如下代码:

async articleRequests(
  accepted?: ArticleRequestAcceptance,
): Promise<ArticleRequest[]> {
  const where: FindConditions<ArticleRequest>[] | FindConditions<ArticleRequest> = {};

  if (accepted !== undefined) {
    switch (accepted) {
      case ArticleRequestAcceptance.Accepted:
        where.accepted = true;
        break;
      case ArticleRequestAcceptance.Rejected:
        where.accepted = false;
        break;
      case ArticleRequestAcceptance.NotReviewedYet:
        where.accepted = undefined;
        break;
    }
  }

  return await ArticleRequest.find({ where }).catch(reason => {
    throw reason.message;
  });
}

TypeORM 为您提供一个 SQL 查询,如下所示:

SELECT '...' WHERE "ArticleRequest"."accepted" = NULL

因为,从 TypeORM 日志输出中可以看出,... WHERE "ArticleRequest"."accepted" = @0 -- PARAMETERS: [null],具有 undefined 值的属性(在本例中为 accepted)在内部转换为 nulls参数数组,然后将它们简单地注入到 SQL 字符串中。

SQL 标准表示与 null 的任何比较都会导致 null 因此对于比较运算符,如 =<>,在 SQL 这应该是没有意义的,但原因是与 null 比较意味着 "unknown" 所以这样的查询不会 return 任何结果。如果你问我,SQL这里坏了。

所以是的,正如@hungneox 所说,解决方案是使用 IsNull(),其中 return 是一个特殊的 FindOperator 用于您需要查询的特定列 IS NULL 而不是 = NULL.

像这样:

  if (accepted !== undefined) {
    switch (accepted) {
      case ArticleRequestAcceptance.Accepted:
        where.accepted = true;
        break;
      case ArticleRequestAcceptance.Rejected:
        where.accepted = false;
        break;
      case ArticleRequestAcceptance.NotReviewedYet:
        where.accepted = IsNull();
        break;
    }
  }

如果有人要找NOT NULL,应该是这样的:

import { IsNull, Not } from "typeorm";

return await getRepository(User).findOne({
    where: { 
      username: Not(IsNull())
    }
});

TheModel.find({ theField: null })

如您所愿。