Relaciones Ansiosas y Perezosas
Esta página fue traducida por PageTurner AI (beta). No está respaldada oficialmente por el proyecto. ¿Encontraste un error? Reportar problema →
Relaciones ansiosas
Las relaciones ansiosas se cargan automáticamente cada vez que recuperas entidades desde la base de datos. Por ejemplo:
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[]
}
Ahora, cuando cargas preguntas no necesitas hacer JOIN ni especificar qué relaciones quieres cargar. Se cargarán automáticamente:
const questionRepository = dataSource.getRepository(Question)
// questions will be loaded with its categories
const questions = await questionRepository.find()
Las relaciones ansiosas solo funcionan con métodos find*.
Si usas QueryBuilder, las relaciones ansiosas se desactivan y debes usar leftJoinAndSelect para cargar la relación.
Las relaciones ansiosas solo pueden usarse en un lado de la relación:
activar eager: true en ambos lados no está permitido.
Por defecto, las relaciones ansiosas se cargan usando LEFT JOIN. Si la relación también está marcada como nullable: false (y posee la columna de unión, es decir ManyToOne o OneToOne propietario), TypeORM usa INNER JOIN en su lugar, lo que puede generar planes de consulta más eficientes.
Estrategia de carga de relaciones
Por defecto, las relaciones ansiosas se cargan añadiendo SQL JOINs a la consulta principal (estrategia "join"). Si estás cargando demasiados datos con uniones anidadas, puedes cambiar a la estrategia "query", que carga las relaciones mediante consultas de base de datos separadas:
// per-query
const questions = await questionRepository.find({
relationLoadStrategy: "query",
})
// or set as the default for the entire DataSource
const dataSource = new DataSource({
// ...
relationLoadStrategy: "query",
})
También puedes controlar si se cargan las relaciones ansiosas 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,
})
Relaciones perezosas
Las entidades en relaciones perezosas se cargan cuando las accedes.
Estas relaciones deben tener tipo Promise: almacenas el valor en una promesa
y al cargarlas también obtienes una promesa. Ejemplo:
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 es una Promise. Significa que es perezosa y solo puede almacenar una promesa con un valor interno.
Ejemplo de cómo guardar esta relación:
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)
Ejemplo de cómo cargar objetos en relaciones perezosas:
const [question] = await dataSource.getRepository(Question).find()
const categories = await question.categories
// you'll have all question's categories inside "categories" variable now
Nota: si vienes de otros lenguajes (Java, PHP, etc.) y estás acostumbrado a usar relaciones perezosas en todos lados - ten cuidado. Esos lenguajes no son asíncronos, y la carga perezosa se implementa diferente, sin usar promesas. En JavaScript y Node.JS, debes usar promesas para tener relaciones de carga perezosa. Esta es una técnica no estándar y se considera experimental en TypeORM.