TypeOrm - findOne 返回意外值

bon*_*low 12 typescript typeorm

我有一个带有电子邮件列的用户实体。当我使用 TypeORM 的 findOne 函数搜索数据库中不存在的电子邮件时,出于某种原因,findOne 将第一个条目返回给用户实体。此功能似乎不像文档中那样工作。

找一个:

// returns the first User of database
const user = await this.userRepository.findOne({ email: 'this@mailisnotindatabase.de' });
Run Code Online (Sandbox Code Playgroud)

用户.Entity.ts:

import {
  Entity,
  Column,
  PrimaryGeneratedColumn,
} from 'typeorm';

@Entity()
export class User {
  @PrimaryGeneratedColumn({ name: 'id' })
  private _id: number;

  @Column({ name: 'password', length: 256, nullable: true })
  private _password?: string;

  @Column({ name: 'email', length: 300, nullable: true, unique: true })
  private _email?: string;

  @Column({ name: 'roles', length: 300, nullable: true })
  private _roles?: string = null;

  public get id(): number {
    return this._id;
  }

  public set id(id: number) {
    this._id = id;
  }

  public get email(): string {
    return this._email;
  }

  public set email(email: string) {
    this._email = email;
  }

  public get password(): string {
    return this._password;
  }

  public set password(password: string) {
    this._password = password;
  }

  public get roles(): string {
    return this._roles;
  }

  public set roles(roles: string) {
    this._roles = roles;
  }
}
Run Code Online (Sandbox Code Playgroud)

这是来自官方文档:

const user = new User(); user.firstName = "木材"; user.lastName = "看到了"; 用户年龄 = 25; 等待 repository.save(user);

const allUsers = await repository.find(); const firstUser = await repository.findOne(1); // 通过 id 查找 const wood = await repository.findOne({ firstName: "Timber", lastName: "Saw" });

等待 repository.remove(timber);

cha*_*avy 10

对我有用:

const user = await this.userRepository.findOne(
    { where:
        { email: 'this@mailisnotindatabase.de' }
    }
);
Run Code Online (Sandbox Code Playgroud)


Est*_*rai 5

这是一个活跃的问题,可以在以下链接中进行讨论: https ://github.com/typeorm/typeorm/issues/2500

我对这个问题的解决方法如下:

const usersRepository = conn.getRepository(UserEntity);

const results = await usersRepository.find({
    relations: ['profile'],
        where: {
            email: username
        },
        take: 1 
    });
// ...
Run Code Online (Sandbox Code Playgroud)

find将返回一个数组,您应该检查数组的长度以确认行与WHERE执行的子句匹配。

当前findOne实现中发生的情况是,当未找到具有所需值的行时,将返回相关表的第一行。

希望这可以帮助!


0xb*_*eny 5

要应用条件,您应该使用 findOne 对象中的 where key 作为参数,如下例所示:

const user = await this.userRepository.findOne({ where:{ email:'this@mailisnotindatabase.de' }});
Run Code Online (Sandbox Code Playgroud)

这是所有查找方法选项的文档: https://github.com/typeorm/typeorm/blob/master/docs/find-options.md


Ale*_*ksi 4

由于User.emailproperty 是一个函数而不是一个字符串,因此您的findOne查询本质上是试图找到一个函数email等于的实体'this@mailisnotindatabase.de',这自然是行不通的。模型中的实际电子邮件列是_email,它作为私有属性无法在 TypeORM 查询中引用。

这里有几个选项:

  1. 摆脱你的 getter 和 setter。TypeORM不支持这种形式的封装。相反,您可以使用另一个域模型类包装 TypeORM 实体类进行封装,或者如果您在 db insert/select 之前使用 getter/setter 来转换值,则可以使用TypeORM 的值转换器

  2. 用于QueryBuilder查询而不是find/ findOne/etc 方法。QueryBuilder 可以引用任意列