TypeORM,根据关系查询实体属性

TypeORM, Query entity based on relation property

我想根据相关属性查询一个实体,例如:

const x = await repo.findOne({ name: 'foo', parent: { name: 'foo' }});

但是当我通过其相关的 parent

进行查询时,它消失了 returns 一个 null

我已添加:relations: ['parent'],已将关系设置为 {eager:true}

当我通过 parent: {id: X} 查询时,它起作用了。但我必须通过它的名字来查询。

我应该怎么做才能使此查询在 TypeORM 中正常工作

类似于:

select * from entity inner join parent ... 其中 entity.name = 'foo' and parent.name = 'foo'

find/findOne 不允许按嵌套关系属性进行过滤。去 QueryBuilder 而不是

const x = await repo.createQueryBuilder("foo")
    .innerJoinAndSelect("foo.parent", "parent")
    .where("parent.name = :name", { name })
    .getOne()

检查 here 是否有类似问题。

我最近发现了一种基于 findOne()/find() 方法的关系字段进行过滤的变通方法。过滤相关 table 字段的问题仅存在于 ObjectLiteral 样式 where,而字符串条件完美无缺。

假设我们有两个实体——UserRole,用户属于一个角色,角色有多个用户:

@Entity()
export class User {
  name: string;

  @ManyToOne(() => Role, role => role.users)
  role: Role;
}

@Entity()
export class Role {
  @OneToMany(() => User, user => user.role)
  users: User[];
}

现在我们可以调用 EntityManager 或存储库的 findOne()/find() 方法:

roleRepository.find({
  join: { alias: 'roles', innerJoin: { users: 'roles.users' } },
  where: qb => {
    qb.where({ // Filter Role fields
      a: 1,
      b: 2
    }).andWhere('users.name = :userName', { userName: 'John Doe' }); // Filter related field
  }
});

如果您已将您的关系标记为热切关系,则可以省略 join 部分。

我建议先在 parent 中获取 id 的列表。

const searchTerm = 'foo'
const parents = await parentRepo.find({name:searchTerm})
const parentIdList = parents.map(parent=>parent.id)
const x = await repo.find({ where:[{name: searchTerm}, {parent: In(parentIdList)}]});

这将为您提供所有名字为 'foo' 或 parent 的名字为 'foo' 的孩子。

尝试使用@gradii/fedaco。与 laravel eloquent.

相同
export class Role {
  @HasManyColumn({related: User, onQuery: (q)=>{
    q.whereColumn('name', 'foo')
  }})
  users: Promise<User[]>;
}

export class Role {
  @HasManyColumn({related: User)
  users: Promise<User[]>;
}
const result = await Role.newRelation('users').whereColumn('name', 'foo').get()