选择带有关系(TypeORM)的repository.find()上的属性

时间:2019-07-10 06:12:32

标签: javascript typescript typeorm

我的方法返回带有所有User对象的账单对象。 我希望我只返回在实体中具有两个属性的帐单对象和用户。我使用TypeORM

  /**
   * Returns a bills by account bill
   */
  async getByAccountBill(
    accountBill: string,
    id?: number
  ): Promise<Object | undefined> {
    const userService = new UserService();
    const user = await userService.getById(id);

    const bills = await this.billRepository.find({
      select: ["accountBill"],
      where: {
        accountBill: Like(`${accountBill}%`),
        user: Not(`${user.id}`)
      },
      relations: ["user"] // I get All object Entity (userId, password, login...) I want to only name and surname
    });

    if (bills) {
      return bills;
    } else {
      return undefined;
    }
  }

3 个答案:

答案 0 :(得分:2)

有点晚了,但对于访问此页面的所有其他人可能会有所帮助 typeorm 中有一个可用选项,因此我们可以按照我们想要的方式获得结果。

enter image description here enter image description here

答案 1 :(得分:0)

您可以使用作为TypeOrm功能最强大的工具之一的querybuilder。

const values = this.billRepository.createQueryBuilder("bill")
    .leftJoinAndSelect("bill.user", "user")
    .where("bill.accountBill LIKE :accountBill", {accountBill})
    .andWhere("user.id = :userId", {userId: user.id})
    .select(["user.name", "user.surname"])
    .execute();

答案 2 :(得分:-1)

如果有人感兴趣,请提供与关系和回购链接相关的简短代码...

https://github.com/typeorm/typeorm/blob/master/src/find-options/FindOptionsUtils.ts

    /**
     * Applies give find options to the given query builder.
     */
    static applyOptionsToQueryBuilder<T>(qb: SelectQueryBuilder<T>, options: FindOneOptions<T> | FindManyOptions<T> | undefined): SelectQueryBuilder<T>;
...
        if (options.loadRelationIds === true) {
            qb.loadAllRelationIds();
        }
        else if (options.loadRelationIds instanceof Object) {
            qb.loadAllRelationIds(options.loadRelationIds);
        }

https://github.com/typeorm/typeorm/blob/master/src/query-builder/SelectQueryBuilder.ts

/**
 * Loads all relation ids for all relations of the selected entity.
 * All relation ids will be mapped to relation property themself.
 * If array of strings is given then loads only relation ids of the given properties.
 */
loadAllRelationIds(options?: { relations?: string[], disableMixedMap?: boolean }): this { // todo: add skip relations
    this.expressionMap.mainAlias!.metadata.relations.forEach(relation => {
        if (options !== undefined && options.relations !== undefined && options.relations.indexOf(relation.propertyPath) === -1)
            return;

        this.loadRelationIdAndMap(
            this.expressionMap.mainAlias!.name + "." + relation.propertyPath,
            this.expressionMap.mainAlias!.name + "." + relation.propertyPath,
            options
        );
    });
    return this;
}

/**
 * LEFT JOINs relation id and maps it into some entity's property.
 * Optionally, you can add condition and parameters used in condition.
 */
loadRelationIdAndMap(mapToProperty: string, relationName: string, options?: { disableMixedMap?: boolean }): this;

/**
 * LEFT JOINs relation id and maps it into some entity's property.
 * Optionally, you can add condition and parameters used in condition.
 */
loadRelationIdAndMap(mapToProperty: string, relationName: string, alias: string, queryBuilderFactory: (qb: SelectQueryBuilder<any>) => SelectQueryBuilder<any>): this;

/**
 * LEFT JOINs relation id and maps it into some entity's property.
 * Optionally, you can add condition and parameters used in condition.
 */
loadRelationIdAndMap(mapToProperty: string,
                     relationName: string,
                     aliasNameOrOptions?: string|{ disableMixedMap?: boolean },
                     queryBuilderFactory?: (qb: SelectQueryBuilder<any>) => SelectQueryBuilder<any>): this {

    const relationIdAttribute = new RelationIdAttribute(this.expressionMap);
    relationIdAttribute.mapToProperty = mapToProperty;
    relationIdAttribute.relationName = relationName;
    if (typeof aliasNameOrOptions === "string")
        relationIdAttribute.alias = aliasNameOrOptions;
    if (aliasNameOrOptions instanceof Object && (aliasNameOrOptions as any).disableMixedMap)
        relationIdAttribute.disableMixedMap = true;

    relationIdAttribute.queryBuilderFactory = queryBuilderFactory;
    this.expressionMap.relationIdAttributes.push(relationIdAttribute);

    if (relationIdAttribute.relation.junctionEntityMetadata) {
        this.expressionMap.createAlias({
            type: "other",
            name: relationIdAttribute.junctionAlias,
            metadata: relationIdAttribute.relation.junctionEntityMetadata
        });
    }
    return this;
}

https://github.com/typeorm/typeorm/blob/master/src/query-builder/relation-id/RelationIdAttribute.ts

/**
 * Stores all join relation id attributes which will be used to build a JOIN query.
 */
export class RelationIdAttribute {

    // -------------------------------------------------------------------------
    // Public Properties
    // -------------------------------------------------------------------------

    /**
     * Alias of the joined (destination) table.
     */
    alias?: string;

    /**
     * Name of relation.
     */
    relationName: string;

    /**
     * Property + alias of the object where to joined data should be mapped.
     */
    mapToProperty: string;

    /**
     * Extra condition applied to "ON" section of join.
     */
    queryBuilderFactory?: (qb: SelectQueryBuilder<any>) => SelectQueryBuilder<any>;

    /**
     * Indicates if relation id should NOT be loaded as id map.
     */
    disableMixedMap = false;
...