【问题标题】:TypeORM, Query entity based on relation propertyTypeORM,根据关系属性查询实体
【发布时间】:2019-12-30 00:49:14
【问题描述】:

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

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

但是当我通过它的相关parent查询时它会返回一个空值

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

当我通过parent: {id: X} 查询时,它可以工作。但我必须按其名称查询。

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

类似于:

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

【问题讨论】:

    标签: typeorm


    【解决方案1】:

    尝试使用@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()
    

    【讨论】:

    • 这如何应用于 TypeORM?
    【解决方案2】:

    我建议先在父级中获取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' 的孩子。

    【讨论】:

      【解决方案3】:

      我最近发现了一种基于findOne()/find() 方法的关系字段进行过滤的解决方法。过滤相关表字段的问题只存在于ObjectLiteral-style 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 部分。

      【讨论】:

      • 有谁知道如何说qb 属性类型来修复缺少的类型?提前致谢!
      • @btd1337 WhereExpression 是你所需要的
      【解决方案4】:

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

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

      查看here 是否有类似问题。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-12-27
        • 2021-08-10
        • 1970-01-01
        相关资源
        最近更新 更多