TypeORM postgresql отношения загрузки, определенные как ленивые - PullRequest
0 голосов
/ 14 сентября 2018

Я пытаюсь найти наилучший способ (или метод наилучшей практики) для разрешения ленивых отношений в моем приложении Nestjs TypeORM postgresql.

Я определил некоторые отношения OneToMany и ManyToOne в объектахкак ленивый, и когда я запрашиваю массив одной из этих сущностей, лучшее решение, которое я нашел до сих пор, - это огромная путаница обещаний.

Моя Customer сущность (customer.entity.ts):

import { Column, CreateDateColumn, Entity, Index, PrimaryGeneratedColumn, UpdateDateColumn, ManyToOne, OneToMany } from 'typeorm';
import { IsEmail } from 'class-validator';
import { ReservationDate } from '../reservation_date/reservation_date.entity';

@Entity()
export class Customer {
    @PrimaryGeneratedColumn('uuid')
    id: string;

    @Index()
    @Column()
    @IsEmail()
    email: string;

    @Column()
    firstName: string;

    @Column()
    lastName: string;

    @CreateDateColumn()
    createDate: Date;

    @UpdateDateColumn()
    updateDate: Date;

    @OneToMany(type => ReservationDate, reservationDate => reservationDate.customer)
    reservationDates: Promise<ReservationDate[]>;
}

и моя ReservationDate сущность (booking_date.entity.ts):

import { Column, CreateDateColumn, Entity, PrimaryGeneratedColumn, UpdateDateColumn, ManyToOne } from 'typeorm';
import { Customer } from '../customer/customer.entity';

@Entity()
export class ReservationDate {
    @PrimaryGeneratedColumn('uuid')
    id: string;

    @Column()
    date: Date;

    @CreateDateColumn()
    createDate: Date;

    @UpdateDateColumn()
    updateDate: Date;

    @ManyToOne(type => Customer, customer => customer.reservationDates, { onDelete: 'CASCADE' })
    customer: Promise<Customer>;
}

Мне нужно получить массив ReservationDate с и отправить его куда-нибудь,но мне нужно, чтобы разрешить поле customer (например, с нетерпением загрузить эти отношения).Вот что «работает»:

const reservationDates: ReservationDate[] = await this.reservationDateRepository
    .createQueryBuilder('reservationDate')
    .leftJoinAndSelect('reservationDate.customer', 'customer')
    .getMany();

// Same result as query builder above
// const reservationDates: ReservationDate[] = await this.reservationDateRepository
//     .find({
//         relations: ['customer'],
//         take: 5
//     });

console.log(reservationDates[0].car);      // => Promise { <pending> }
console.log(reservationDates[0].__car__);  // => Car { id: string, owner... }

// this is where it gets ugly
const reservationDatesWithResolvedRelationships = await Promise.all(
    reservationDates.map(async (resDate: ReservationDate) => {
        const withResolved: ReservationDateRepoObject = { ...resDate };

        withResolved.customer = await resDate.customer;

        return withResolved;
    })
);

console.log(reservationDatesWithResolvedRelationships[0].car);  // => Car { id: string, owner... }

// send off the JSON-like object here

Я чувствую, что должен быть способ объединения и принудительной загрузки, но ни построитель запросов, ни методы repository.find, похоже, не делают этого скак я это настроил.

Я также пытался добавить { lazy: true } и { eager: true } к отношениям в сущностях, но ничего не изменилось.

РЕДАКТИРОВАТЬ:

Пока еще немного удачи, однако мне удалось взломать псевдо-решение.

private parseRaw = name => raw => {
    const parsed = new ReservationDate();
    Object.entries(raw).forEach(([typeKey, value]) => {
        const [type, key] = typeKey.split('_');
        if (type === name) {
            parsed[key] = value;
        } else {
            parsed[type] = parsed[type] || {};
            parsed[type][key] = value;
        }
    });
    return parsed;
};

let reservationDates: ReservationDate[] = (await this.reservationDateRepository
    .createQueryBuilder('reservationDate')
    .leftJoinAndSelect('reservationDate.customer', 'customer')
    .limit(5)
    .getRawMany()).map(this.parseRaw('reservationDate'));

Супер-уродливый взлом, но он конвертирует необработанные результаты snake_case db в camelCase json-объектМне нужно отправить ...

...