Vai al contenuto principale

Relazioni Eager e Lazy

Traduzione Beta Non Ufficiale

Questa pagina è stata tradotta da PageTurner AI (beta). Non ufficialmente approvata dal progetto. Hai trovato un errore? Segnala problema →

Relazioni Eager

Le relazioni eager vengono caricate automaticamente ogni volta che carichi le entità dal database. Per esempio:

import { Entity, PrimaryGeneratedColumn, Column, ManyToMany } from "typeorm"
import { Question } from "./Question"

@Entity()
export class Category {
@PrimaryGeneratedColumn()
id: number

@Column()
name: string

@ManyToMany((type) => Question, (question) => question.categories)
questions: Question[]
}
import {
Entity,
PrimaryGeneratedColumn,
Column,
ManyToMany,
JoinTable,
} from "typeorm"
import { Category } from "./Category"

@Entity()
export class Question {
@PrimaryGeneratedColumn()
id: number

@Column()
title: string

@Column()
text: string

@ManyToMany((type) => Category, (category) => category.questions, {
eager: true,
})
@JoinTable()
categories: Category[]
}

Ora, quando carichi le domande non devi eseguire join o specificare le relazioni da caricare. Verranno caricate automaticamente:

const questionRepository = dataSource.getRepository(Question)

// questions will be loaded with its categories
const questions = await questionRepository.find()

Le relazioni eager funzionano solo con i metodi find*. Se usi QueryBuilder le relazioni eager sono disabilitate e devi usare leftJoinAndSelect per caricare la relazione. Le relazioni eager possono essere utilizzate solo su un lato della relazione: usare eager: true su entrambi i lati non è consentito.

Di default, le relazioni eager vengono caricate usando LEFT JOIN. Se la relazione è anche marcata come nullable: false (e possiede la colonna di join, ad esempio ManyToOne o OneToOne proprietaria), TypeORM utilizza invece INNER JOIN, che può produrre piani di query più efficienti.

Strategia di caricamento delle relazioni

Per impostazione predefinita, le relazioni eager vengono caricate aggiungendo JOIN SQL alla query principale (strategia "join"). Se stai caricando troppi dati con join nidificati, puoi passare alla strategia "query", che carica le relazioni tramite query di database separate invece:

// per-query
const questions = await questionRepository.find({
relationLoadStrategy: "query",
})

// or set as the default for the entire DataSource
const dataSource = new DataSource({
// ...
relationLoadStrategy: "query",
})

Puoi anche controllare se le relazioni eager vengono caricate o meno usando loadEagerRelations:

// disable eager relation loading entirely
const questions = await questionRepository.find({
loadEagerRelations: false,
})

// load explicit relations only, suppress nested eager relations
const questions = await questionRepository.find({
relations: { categories: true },
loadEagerRelations: false,
})

Relazioni Lazy

Le entità nelle relazioni lazy vengono caricate quando vi accedi. Queste relazioni devono avere tipo Promise: memorizzi il valore in una promise e quando le carichi viene restituita una promise. Esempio:

import { Entity, PrimaryGeneratedColumn, Column, ManyToMany } from "typeorm"
import { Question } from "./Question"

@Entity()
export class Category {
@PrimaryGeneratedColumn()
id: number

@Column()
name: string

@ManyToMany((type) => Question, (question) => question.categories)
questions: Promise<Question[]>
}
import {
Entity,
PrimaryGeneratedColumn,
Column,
ManyToMany,
JoinTable,
} from "typeorm"
import { Category } from "./Category"

@Entity()
export class Question {
@PrimaryGeneratedColumn()
id: number

@Column()
title: string

@Column()
text: string

@ManyToMany((type) => Category, (category) => category.questions)
@JoinTable()
categories: Promise<Category[]>
}

categories è una Promise. Significa che è lazy e può contenere solo una promise con un valore al suo interno. Esempio di come salvare questa relazione:

const category1 = new Category()
category1.name = "animals"
await dataSource.manager.save(category1)

const category2 = new Category()
category2.name = "zoo"
await dataSource.manager.save(category2)

const question = new Question()
question.categories = Promise.resolve([category1, category2])
await dataSource.manager.save(question)

Esempio di come caricare gli oggetti nelle relazioni lazy:

const [question] = await dataSource.getRepository(Question).find()
const categories = await question.categories
// you'll have all question's categories inside "categories" variable now

Nota: se provieni da altri linguaggi (Java, PHP, ecc.) e sei abituato a usare relazioni lazy ovunque - fai attenzione. Quei linguaggi non sono asincroni e il lazy loading viene implementato diversamente, senza promise. In JavaScript e Node.JS devi usare le promise per avere relazioni lazy. Questa tecnica non è standard ed è considerata sperimentale in TypeORM.