TypeORM,基于关系属性查询实体

问题描述 投票:0回答:6

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

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

但当我通过其相关查询时,它会返回 null

parent

我已经添加:

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

当我通过

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

我应该怎么做才能让这个查询在 TypeORM 中工作

它类似于:

从实体内连接父级中选择*...其中entity.name = 'foo'并且parent.name = 'foo'

typeorm
6个回答
32
投票

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

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

查看此处是否有类似问题。

编辑:

typeorm >= 0.3
现在支持按关系查询。有关详细信息,请参阅发行说明


11
投票

我最近发现了一种基于

findOne()
/
find()
方法的关系字段进行过滤的解决方法。过滤相关表字段的问题仅存在于
ObjectLiteral
样式
where
,而字符串条件则完美。

假设我们有两个实体——

User
Role
,用户属于一个角色,角色有多个用户:

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

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

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

现在我们可以调用

findOne()
或存储库的
find()
/
EntityManager
方法:

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
部分。


3
投票

我知道这个答案在需要时是无关紧要的,但出于进一步的目的。

typeorm^0.3 above
现在可以直接进行这样的查询,就像你想要的那样。


1
投票

如果你想使用 repo 模式:

const data = await this.repo.findOne({
    where: {
        parent: {
            name: 'some name',
            // id: Not(IsNull()), // parent (not)exist - this can helpful for someone
        },
    },
    // relations: ['parent'], // if you need this relation
});

0
投票

我建议首先在父级中获取

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”或其父母名字为“foo”的孩子。


0
投票

另一种选择,无需添加

.where

const x = await repo.createQueryBuilder("foo")
    .innerJoinAndSelect("foo.parent", "parent", "parent.name = :name", { name })
    .getOne()
© www.soinside.com 2019 - 2024. All rights reserved.