繁体   English   中英

使用关系(TypeORM)选择 repository.find() 上的属性

[英]Select attributes on repository.find() with relations (TypeORM)

我的方法返回一个带有所有用户对象的账单对象。 我希望我只返回具有实体中两个属性的账单对象和用户。 我使用 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;
    }
  }

您可以使用 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();
// NOTE
// .execute() will return raw results.
// To return objects, use .getMany()

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

return this.repository.find({
  relations: ['user'],
  loadRelationIds: true,
  where: { ... },
  order: { ... }
});

在此处输入图像描述

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

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM