TypeOrm-findOne返回意外值

时间:2018-11-24 05:53:37

标签: typescript typeorm

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

findOne:

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

User.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;
  }
}

这是来自官方文档:

  

const user = new User(); user.firstName =“木材”; user.lastName =   “锯”; user.age = 25;等待repository.save(user);

     

const allUsers =等待repository.find(); const firstUser =等待   repository.findOne(1); //通过id查找const timber = await   repository.findOne({firstName:“ Timber”,lastName:“ Saw”});

     

等待repository.remove(木材);

5 个答案:

答案 0 :(得分:1)

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

这里有两个选择:

  1. 摆脱您的getter和setter。 TypeORM does not support这种封装形式。相反,您可以将TypeORM Entity类与另一个域模型类包装在一起进行封装,或者如果在数据库插入/选择之前使用getters / setters方法转换值,则可以使用TypeORM's value transformers

  2. 对您的查询使用QueryBuilder而不是find / findOne / etc方法。 QueryBuilder can refer to any arbitrary column

答案 1 :(得分:1)

这是一个活跃的问题,下面的链接中提供了讨论: https://github.com/typeorm/typeorm/issues/2500

我在此问题上的解决方法如下:

const usersRepository = conn.getRepository(UserEntity);

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

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

当前findOne实现的结果是,当找不到具有所需值的行时,将返回有问题的表的第一行。

希望这会有所帮助!

答案 2 :(得分:0)

为我工作:

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

答案 3 :(得分:0)

ORM类型对我有用:

let userData;
let userRepository = getRepository(User);
userData = await userRepository
                .findOne({
                    where: {"email":'navalkishor2005@gmail.com'}
                });

答案 4 :(得分:0)

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

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

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