Modellare le relazioni tra table in Dataverse

In Dataverse ogni relazione è definita da una lookup column: quando crei una relazione 1:N (one-to-many), Dataverse aggiunge automaticamente una colonna lookup sulla table “molti” che punta alla table “uno”. La stessa relazione, vista dal lato opposto, è una N:1 (many-to-one): non sono due relazioni diverse ma due prospettive dello stesso oggetto. Come functional consultant devi ragionare su chi è il parent (la “uno”) e chi è il child (la “molti”), perché è questa gerarchia a governare sia i comportamenti a cascata sia la sicurezza.

Relazioni N:N: intersect nativa vs manuale

Per associare molti record a molti record (es. ContactMarketing List) hai due strade:

  • N:N nativa (managed intersect table): Dataverse crea e gestisce internamente la intersect table, che contiene solo le due chiavi. È semplice, si configura senza codice, ma non può portare attributi propri (niente date, quantità, note sulla relazione) né logica/plugin dedicati.
  • N:N manuale (custom intersect / associative entity): crei tu una table intermedia con due lookup 1:N verso le table da collegare. Serve quando la relazione stessa ha dei dati — pensa a Enrollment tra Student e Course con voto e data. Questa è la scelta corretta ogni volta che devi salvare informazioni “sul legame”.

Regola pratica d’esame: se lo scenario richiede attributi o business logic sulla relazione, scegli sempre l’intersect manuale.

Comportamenti a cascata (relationship behaviors)

Sul lato 1:N configuri come le azioni sul parent si propagano ai child. Le opzioni preconfigurate sono Parental, Referential, Referential – Restrict Delete e Configurable Cascade (custom). Le azioni cascadibili sono quattro:

  • Assign: cambio di owner del parent.
  • Share / Unshare: condivisione del parent con altri utenti/team.
  • Delete: eliminazione del parent.
  • Reparent: il child segue la sicurezza del nuovo parent quando cambia il valore della lookup.

Per ciascuna azione i valori possibili sono Cascade All, Cascade Active, Cascade User-owned, Cascade None e — solo per Delete — Restrict.

I preset in sintesi

  • Parental: tutto in Cascade All. Elimini il parent → spariscono tutti i child; riassegni il parent → si riassegnano anche i child. Massimo accoppiamento.
  • Referential: le operazioni restano indipendenti; sul Delete il valore è Remove Link, quindi il child sopravvive e la lookup viene svuotata.
  • Referential – Restrict Delete: come sopra, ma il Delete è Restrict: se esistono child, l’eliminazione del parent viene bloccata.

Alternate key e upsert

Per default un record si identifica con il suo GUID (primary key), sconosciuto ai sistemi esterni. Le alternate key ti permettono di dichiarare come chiave alternativa una o più business column (es. Account Number, oppure la coppia Email + Region) che devono essere univoche. Servono soprattutto per:

  • Upsert: in un import o via Dataverse connector, l’operazione fa update se la chiave esiste, altrimenti insert — senza dover conoscere il GUID.
  • Integrazione con sistemi esterni: aggancio dei record tramite codici di business già presenti nel gestionale/ERP, evitando duplicati.

Vincoli da ricordare: le alternate key si appoggiano a colonne di tipo supportato (testo, numeri, lookup, date, ecc.), la loro creazione è asincrona (job di indicizzazione, stato Active prima dell’uso) e impongono unicità a livello di table.

Trappole tipiche d’esame

  • Scenario: cancellando un Account non devono sparire le Case collegate, ma l’operazione deve essere impedita finché esistono. → Imposta il behavior su Referential – Restrict Delete (Delete = Restrict), non Parental.
  • Scenario: eliminando un parent i child devono essere eliminati automaticamente. → Serve Cascade All sul Delete (preset Parental); “Referential” lascerebbe i child orfani con lookup svuotata.
  • Scenario: relazione molti-a-molti che deve memorizzare data e ruolo dell’associazione. → N:N manuale con intersect table custom; la N:N nativa non porta attributi.
  • Scenario: import da ERP che deve aggiornare i record esistenti senza duplicare, senza conoscere il GUID. → Definisci una alternate key sulla business column e usa l’upsert.
  • Scenario: riassegnando l’owner di un parent, tutti i child devono cambiare owner. → Configura Cascade sull’azione Assign (Parental o Configurable Cascade); Referential non propaga l’Assign.