5

重现步骤:

  1. 创建 2 个架构ab
  2. 使用这些各自的实体在两个模式中创建表用户,照片UserA PhotoAUserB PhotoB
// PhotoA
import {Entity, Column, PrimaryGeneratedColumn, ManyToOne} from "typeorm";
import { User as UserB } from "./User.b";
import { User as UserA } from "./User.a";

@Entity({schema: "a"})
export class Photo {

    @PrimaryGeneratedColumn()
    id: number;

    @Column({
        length: 100
    })
    name: string;

    @ManyToOne(type => UserA)
    userA: UserA;
    @ManyToOne(type => UserB)
    userB: UserB;
}
// UserB
import {Entity, Column, PrimaryGeneratedColumn, OneToMany} from "typeorm";
import { Photo as PhotoA } from "./Photo.a";
import { Photo as PhotoB } from "./Photo.b";

@Entity({schema: "b"})
export class User {

    @PrimaryGeneratedColumn()
    id: number;

    @Column({
        length: 100
    })
    name: string;

    @OneToMany(type => PhotoA, photo => photo.userB)
    photosA: PhotoA[]
    @OneToMany(type => PhotoB, photo => photo.userB)
    photosB: PhotoB[]
}
  1. 运行此代码
import "reflect-metadata";
import * as typeorm from "typeorm";
import { Photo as PhotoA } from "./entities/Photo.a";
import { User as UserB } from "./entities/User.b";
import { PostgresConnectionOptions } from "typeorm/driver/postgres/PostgresConnectionOptions";
import { Photo as PhotoB } from "./entities/Photo.b";
import { User as UserA } from "./entities/User.a";

class Inl {
    public async test() {
        const connection = await typeorm.createConnection({
            type: "postgres",
            host: "localhost",
            port: 5433,
            username: "test",
            password: "test",
            database: "test",
            synchronize: true,
            logging: true,
            entities: [ PhotoA, PhotoB, UserA, UserB ]
        } as PostgresConnectionOptions);
        const photoARepo = connection.getRepository(PhotoA);
        const userBRepo = connection.getRepository(UserB);
        const userBRow = new UserB();
        userBRow.name = "User in schema B";
        const userBSavedRow = await userBRepo.save(userBRow);
        const photoARow = new PhotoA();
        photoARow.name = "Photo in schema A";
        photoARow.userB = userBSavedRow;

        await photoARepo.save(photoARow);

        const photoBRow = new PhotoB();
        photoBRow.name = "Photo in schema B";
        photoBRow.userB = userBSavedRow;

        await photoARepo.save(photoARow);

        const result = await userBRepo
            .createQueryBuilder("userB")
            .select("*")
            .leftJoinAndSelect("a.photo", "photosA")
            .leftJoinAndSelect("b.photo", "photosB")
            .where({id: userBSavedRow.id})
            .getOne();
        console.log(result);
    }
}
new Inl().test();

结果

query: INSERT INTO "a"."photo"("name", "userAId", "userBId") VALUES ($1, DEFAULT, $2) RETURNING "id" -- PARAMETERS: ["Photo in schema A",6]
query: COMMIT
query: SELECT "Photo"."id" AS "Photo_id", "Photo"."name" AS "Photo_name", "Photo"."userAId" AS "Photo_userAId", "Photo"."userBId" AS "Photo_userBId" FROM "a"."photo" "Photo" WHERE "Photo"."id" IN ($1) -- PARAMETERS: [6]
(node:527) UnhandledPromiseRejectionWarning: Error: "a" alias was not found. Maybe you forgot to join it?
    at QueryExpressionMap.findAliasByName (/home/lewis/Projects/internationalisation/src/query-builder/QueryExpressionMap.ts:341:19)
    at JoinAttribute.getValue (/home/lewis/Projects/internationalisation/src/query-builder/JoinAttribute.ts:146:72)
    at JoinAttribute.get [as relation] (/home/lewis/Projects/internationalisation/src/query-builder/JoinAttribute.ts:162:53)
    at JoinAttribute.get [as metadata] (/home/lewis/Projects/internationalisation/src/query-builder/JoinAttribute.ts:175:18)
    at SelectQueryBuilder.join (/home/lewis/Projects/internationalisation/src/query-builder/SelectQueryBuilder.ts:1299:27)
    at SelectQueryBuilder.leftJoin (/home/lewis/Projects/internationalisation/src/query-builder/SelectQueryBuilder.ts:284:14)
    at SelectQueryBuilder.leftJoinAndSelect (/home/lewis/Projects/internationalisation/src/query-builder/SelectQueryBuilder.ts:364:14)
    at Inl.test (/home/lewis/Projects/internationalisation/index.ts:42:14)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:160:7)

正如您从日志中看到的那样,我alias was not found在上面的代码中遇到了错误。有人对此有提示吗?

4

1 回答 1

2

这里的问题是您在 leftJoinAndSelect 中混合了模式和别名(模式由 TypeOrm 解析,如果您的实体配置正确,则无需在查询中指定它)。所以这应该工作:

const result = await userBRepo
        .createQueryBuilder("userB")
        .leftJoinAndSelect("userB.photosA", "photosA")
        .leftJoinAndSelect("userB.photosB", "photosB")
        .where({id: userBSavedRow.id})
        .getOne();
于 2019-09-10T07:05:29.160 回答