Vai al contenuto principale

Lavorare con le Relazioni

Traduzione Beta Non Ufficiale

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

RelationQueryBuilder è un tipo speciale di QueryBuilder che ti permette di lavorare con le tue relazioni. Utilizzandolo, puoi collegare entità tra loro nel database senza bisogno di caricare alcuna entità, oppure puoi caricare facilmente le entità correlate.

Ad esempio, supponiamo di avere un'entità Post con una relazione many-to-many verso Category chiamata categories. Aggiungiamo una nuova categoria a questa relazione many-to-many:

await dataSource
.createQueryBuilder()
.relation(Post, "categories")
.of(post)
.add(category)

Questo codice è equivalente a:

const postRepository = dataSource.manager.getRepository(Post)
const post = await postRepository.findOne({
where: {
id: 1,
},
relations: {
categories: true,
},
})
post.categories.push(category)
await postRepository.save(post)

Ma è più efficiente perché esegue un numero minimo di operazioni e collega le entità direttamente nel database, a differenza della chiamata all'ingombrante metodo save.

Un ulteriore vantaggio di questo approccio è che non devi caricare tutte le entità correlate prima di aggiungerne di nuove. Ad esempio, se un singolo post ha diecimila categorie, aggiungere nuovi elementi a questa lista potrebbe diventare problematico, perché il metodo standard richiederebbe di caricare il post con tutte le diecimila categorie, aggiungere la nuova categoria, e salvare il tutto. Ciò comporta costi prestazionali molto elevati ed è praticamente inutilizzabile in produzione. Tuttavia, usando RelationQueryBuilder risolvi questo problema.

Inoltre, non è strettamente necessario utilizzare entità intere quando "colleghi" elementi, poiché puoi usare gli ID delle entità. Ad esempio, aggiungiamo una categoria con ID = 3 a un post con ID = 1:

await dataSource.createQueryBuilder().relation(Post, "categories").of(1).add(3)

Se utilizzi chiavi primarie composite, devi passarle come mappa ID, ad esempio:

await dataSource
.createQueryBuilder()
.relation(Post, "categories")
.of({ firstPostId: 1, secondPostId: 3 })
.add({ firstCategoryId: 2, secondCategoryId: 4 })

Puoi rimuovere le entità nello stesso modo in cui le aggiungi:

// this code removes a category from a given post
await dataSource
.createQueryBuilder()
.relation(Post, "categories")
.of(post) // you can use just post id as well
.remove(category) // you can use just category id as well

L'aggiunta e la rimozione di entità correlate funziona per relazioni many-to-many e one-to-many. Per relazioni one-to-one e many-to-one utilizza invece set:

// this code sets category of a given post
await dataSource
.createQueryBuilder()
.relation(Post, "categories")
.of(post) // you can use just post id as well
.set(category) // you can use just category id as well

Se vuoi annullare una relazione (impostarla su null), passa semplicemente null al metodo set:

// this code unsets category of a given post
await dataSource
.createQueryBuilder()
.relation(Post, "categories")
.of(post) // you can use just post id as well
.set(null)

Oltre ad aggiornare le relazioni, il relational query builder ti permette anche di caricare entità correlate. Ad esempio, supponiamo che dentro un'entità Post abbiamo una relazione many-to-many categories e una many-to-one user, per caricare queste relazioni puoi usare il seguente codice:

const post = await dataSource.manager.findOneBy(Post, {
id: 1,
})

post.categories = await dataSource
.createQueryBuilder()
.relation(Post, "categories")
.of(post) // you can use just post id as well
.loadMany()

post.author = await dataSource
.createQueryBuilder()
.relation(Post, "user")
.of(post) // you can use just post id as well
.loadOne()