Condividi tramite


Eliminazione a catena

Entity Framework Core (EF Core) rappresenta le relazioni usando chiavi esterne. Un'entità con una chiave esterna è l'entità figlia o dipendente nella relazione. Il valore della chiave esterna dell'entità deve corrispondere al valore della chiave primaria (o a un valore di chiave alternativo) dell'entità principale/padre correlata.

Se l'entità principale/padre viene eliminata, i valori di chiave esterna dei dipendenti/figli non corrisponderanno più alla chiave primaria o alternativa di qualsiasi entità o padre. Si tratta di uno stato non valido e causerà una violazione del vincolo referenziale nella maggior parte dei database.

Esistono due opzioni per evitare questa violazione del vincolo referenziale:

  1. Impostare i valori FK su Null
  2. Eliminare anche le entità dipendenti/figlio

La prima opzione è valida solo per le relazioni facoltative in cui la proprietà della chiave esterna (e la colonna di database a cui è mappata) deve essere annullabile.

La seconda opzione è valida per qualsiasi tipo di relazione ed è nota come "eliminazione a catena".

Suggerimento

Questo documento descrive le eliminazioni a catena (ed eliminazione di orfani) dal punto di vista dell'aggiornamento del database. Usa molto i concetti introdotti in Rilevamento modifiche in EF Core e Cambiamento delle chiavi esterne e delle navigazioni. Assicurarsi di comprendere appieno questi concetti prima di affrontare il materiale qui.

Suggerimento

È possibile eseguire ed eseguire il debug in tutto il codice di questo documento scaricando il codice di esempio da GitHub.

Quando si verificano comportamenti a catena

Le eliminazioni a catena sono necessarie quando un'entità dipendente/figlio non può più essere associata all'entità principale/padre corrente. Ciò può verificarsi perché l'entità o l'elemento padre viene eliminato oppure può verificarsi quando l'entità o l'elemento padre esiste ancora, ma il dipendente/figlio non è più associato.

Eliminazione di un principale/genitore

Si consideri questo modello semplice dove Blog è l'entità/padre in una relazione con Post, che è il dipendente/figlio. Post.BlogId è una proprietà di chiave esterna, il cui valore deve corrispondere alla Blog.Id chiave primaria del blog a cui appartiene il post.

public class Blog
{
    public int Id { get; set; }

    public string Name { get; set; }

    public IList<Post> Posts { get; } = new List<Post>();
}

public class Post
{
    public int Id { get; set; }

    public string Title { get; set; }
    public string Content { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set; }
}

Per convenzione, questa relazione viene configurata come obbligatoria, poiché la proprietà della chiave esterna Post.BlogId non può essere annullabile. Le relazioni necessarie sono configurate per l'uso di eliminazioni a catena per impostazione predefinita. Per altre informazioni sulla modellazione delle relazioni, vedere Relazioni .

Quando si elimina un blog, tutti i post vengono eliminati a catena. Per esempio:

using var context = new BlogsContext();

var blog = await context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).FirstAsync();

context.Remove(blog);

await context.SaveChangesAsync();

SaveChanges genera il codice SQL seguente, usando SQL Server come esempio:

-- Executed DbCommand (1ms) [Parameters=[@p0='1'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Posts]
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;

-- Executed DbCommand (0ms) [Parameters=[@p0='2'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Posts]
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;

-- Executed DbCommand (2ms) [Parameters=[@p1='1'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Blogs]
WHERE [Id] = @p1;
SELECT @@ROWCOUNT;

Interrompere una relazione

Invece di eliminare il blog, potremmo separare il rapporto tra ogni post e il relativo blog. Questa operazione può essere eseguita impostando la navigazione Post.Blog di riferimento su Null per ogni post:

using var context = new BlogsContext();

var blog = await context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).FirstAsync();

foreach (var post in blog.Posts)
{
    post.Blog = null;
}

await context.SaveChangesAsync();

La relazione può anche essere interrotta rimuovendo ogni post dalla navigazione della raccolta Blog.Posts.

using var context = new BlogsContext();

var blog = await context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).FirstAsync();

blog.Posts.Clear();

await context.SaveChangesAsync();

In entrambi i casi il risultato è lo stesso: il blog non viene eliminato, ma i post che non sono più associati ad alcun blog vengono eliminati:

-- Executed DbCommand (1ms) [Parameters=[@p0='1'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Posts]
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;

-- Executed DbCommand (0ms) [Parameters=[@p0='2'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Posts]
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;

L'eliminazione di entità non più associate ad alcun principale/dipendente è nota come "eliminazione di orfani".

Suggerimento

L'eliminazione a catena e l'eliminazione degli orfani sono strettamente correlate. Entrambi comportano l'eliminazione di entità dipendenti/figlio quando la relazione con l'entità principale/padre richiesta viene interrotta. Per l'eliminazione a catena, questa interruzione avviene perché l'entità principale/genitore viene eliminata. Per gli orfani, l'entità principale/padre esiste ancora, ma non è più correlata alle entità dipendenti/figlio.

Dove si verificano dinamiche a cascata

I comportamenti a catena possono essere applicati a:

  • Entità tracciate dal sistema corrente DbContext
  • Entità nel database che non sono state caricate nel contesto

Eliminazione a catena di entità rilevate

EF Core applica sempre comportamenti di propagazione configurati alle entità rilevate. Ciò significa che se l'applicazione carica tutte le entità dipendenti/figlio rilevanti in DbContext, come illustrato negli esempi precedenti, i comportamenti a catena verranno applicati correttamente indipendentemente dalla modalità di configurazione del database.

Suggerimento

La tempistica esatta di quando si verificano comportamenti a catena alle entità monitorate può essere controllata usando ChangeTracker.CascadeDeleteTiming e ChangeTracker.DeleteOrphansTiming. Per ulteriori informazioni, consultare Modifica delle chiavi esterne e delle navigazioni.

Eliminazione a catena nel database

Molti sistemi di database offrono anche comportamenti a catena attivati quando un'entità viene eliminata nel database. EF Core configura questi comportamenti in base al comportamento di eliminazione a catena nel modello EF Core quando viene creato un database usando EnsureCreated o migrazioni di EF Core. Ad esempio, usando il modello precedente, viene creata la tabella seguente per i post quando si usa SQL Server:

CREATE TABLE [Posts] (
    [Id] int NOT NULL IDENTITY,
    [Title] nvarchar(max) NULL,
    [Content] nvarchar(max) NULL,
    [BlogId] int NOT NULL,
    CONSTRAINT [PK_Posts] PRIMARY KEY ([Id]),
    CONSTRAINT [FK_Posts_Blogs_BlogId] FOREIGN KEY ([BlogId]) REFERENCES [Blogs] ([Id]) ON DELETE CASCADE
);

Si noti che il vincolo di chiave esterna che definisce la relazione tra blog e post è configurato con ON DELETE CASCADE.

Se si sa che il database è configurato in questo modo, è possibile eliminare un blog senza prima caricare post e il database si occupa dell'eliminazione di tutti i post correlati a tale blog. Per esempio:

using var context = new BlogsContext();

var blog = await context.Blogs.OrderBy(e => e.Name).FirstAsync();

context.Remove(blog);

await context.SaveChangesAsync();

Si noti che non c'è un Include per i post, quindi non vengono caricati. SaveChanges in questo caso eliminerà solo il blog, poiché questa è l'unica entità monitorata:

-- Executed DbCommand (6ms) [Parameters=[@p0='1'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Blogs]
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;

Ciò comporta un'eccezione se il vincolo di chiave esterna nel database non è configurato per le eliminazioni a catena. Tuttavia, in questo caso i post vengono eliminati dal database perché è stato configurato con ON DELETE CASCADE quando è stato creato.

Annotazioni

I database in genere non dispongono di alcun modo per eliminare automaticamente gli orfani. Ciò è dovuto al fatto che, mentre EF Core rappresenta le relazioni usando navigazioni e chiavi esterne, i database hanno solo chiavi esterne e nessuna navigazione. Ciò significa che in genere non è possibile interrompere una relazione senza caricare entrambe le parti nel DbContext.

Annotazioni

Il database in memoria di EF Core attualmente non supporta le eliminazioni a catena nel database.

Avvertimento

Non configurare l'eliminazione a catena nel database mentre si eliminano temporaneamente le entità. Ciò può causare l'eliminazione accidentale e definitiva delle entità anziché l'eliminazione temporanea.

Limitazioni a catena del database

Alcuni database, in particolare SQL Server, presentano limitazioni sui comportamenti a catena che formano cicli. Si consideri ad esempio il modello seguente:

public class Blog
{
    public int Id { get; set; }
    public string Name { get; set; }

    public IList<Post> Posts { get; } = new List<Post>();

    public int OwnerId { get; set; }
    public Person Owner { get; set; }
}

public class Post
{
    public int Id { get; set; }
    public string Title { get; set; }
    public string Content { get; set; }

    public int BlogId { get; set; }
    public Blog Blog { get; set; }

    public int AuthorId { get; set; }
    public Person Author { get; set; }
}

public class Person
{
    public int Id { get; set; }
    public string Name { get; set; }

    public IList<Post> Posts { get; } = new List<Post>();

    public Blog OwnedBlog { get; set; }
}

Questo modello ha tre relazioni, tutte necessarie e quindi configurate per l'eliminazione a catena per convenzione:

  • L'eliminazione di un blog eliminerà tutti i post correlati
  • L'eliminazione dell'autore dei post causerà l'eliminazione a catena dei post creati
  • L'eliminazione del proprietario di un blog causerà l'eliminazione a catena del blog

Questo è tutto ragionevole (se un po' draconiani nei criteri di gestione del blog!) ma il tentativo di creare un database di SQL Server con queste cascate configurate comporta l'eccezione seguente.

Microsoft.Data.SqlClient.SqlException (0x80131904): l'introduzione del vincolo FOREIGN KEY 'FK_Posts_Person_AuthorId' nella tabella 'Post' può causare cicli o più percorsi a catena. Specificare ON DELETE NO ACTION o ON UPDATE NO ACTION oppure modificare gli altri vincoli FOREIGN KEY.

Esistono due modi per gestire questa situazione:

  1. Modificare una o più relazioni in modo che non vengano eliminate a catena.
  2. Configurare il database senza una o più di queste eliminazioni a catena, quindi assicurarsi che tutte le entità dipendenti vengano caricate in modo che EF Core possa eseguire il comportamento a catena.

Prendendo il primo approccio con il nostro esempio, possiamo rendere facoltativa la relazione post-blog assegnando una proprietà di chiave esterna annullabile.

public int? BlogId { get; set; }

Una relazione facoltativa consente l'esistenza del post senza un blog, il che significa che l'eliminazione a catena non verrà più configurata per impostazione predefinita. Ciò significa che non è più presente un ciclo nelle azioni a catena e il database può essere creato senza errori in SQL Server.

Prendendo invece il secondo approccio, è possibile mantenere la relazione del proprietario del blog obbligatoria e configurata per l'eliminazione a catena, ma rendere questa configurazione applicabile solo alle entità rilevate, non al database:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<Blog>()
        .HasOne(e => e.Owner)
        .WithOne(e => e.OwnedBlog)
        .OnDelete(DeleteBehavior.ClientCascade);
}

Ora cosa succede se carichiamo sia una persona che il blog di cui sono proprietari, quindi eliminiamo la persona?

using var context = new BlogsContext();

var owner = await context.People.SingleAsync(e => e.Name == "ajcvickers");
var blog = await context.Blogs.SingleAsync(e => e.Owner == owner);

context.Remove(owner);

await context.SaveChangesAsync();

EF Core eseguirà la cancellazione a cascata del proprietario, in modo che il blog venga anch'esso eliminato.

-- Executed DbCommand (8ms) [Parameters=[@p0='1'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Blogs]
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;

-- Executed DbCommand (2ms) [Parameters=[@p1='1'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [People]
WHERE [Id] = @p1;
SELECT @@ROWCOUNT;

Tuttavia, se il blog non viene caricato quando il proprietario viene eliminato:

using var context = new BlogsContext();

var owner = await context.People.SingleAsync(e => e.Name == "ajcvickers");

context.Remove(owner);

await context.SaveChangesAsync();

Verrà quindi generata un'eccezione a causa della violazione del vincolo di chiave esterna nel database:

Microsoft.Data.SqlClient.SqlException: L'istruzione DELETE ha causato un conflitto con il vincolo di riferimento "FK_Blogs_People_OwnerId". Il conflitto si è verificato nel database "Scratch", tabella "dbo. Blogs", colonna 'OwnerId'. La dichiarazione è stata terminata.

Valori nulli a cascata

Le relazioni facoltative hanno proprietà di chiave esterna annullabili, mappate su colonne del database che possono essere annullabili. Ciò significa che il valore della chiave esterna può essere impostato su null quando l'entità principale/padre corrente viene eliminata o viene disconnessa dal dipendente/figlio.

Esaminiamo di nuovo gli esempi di Quando si verificano comportamenti a catena, ma questa volta con una relazione facoltativa rappresentata da una proprietà di chiave esterna nullable Post.BlogId :

public int? BlogId { get; set; }

Questa proprietà di chiave esterna verrà impostata su Null per ogni post quando viene eliminato il blog correlato. Ad esempio, questo codice, uguale a prima:

using var context = new BlogsContext();

var blog = await context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).FirstAsync();

context.Remove(blog);

await context.SaveChangesAsync();

Verranno ora restituiti gli aggiornamenti del database seguenti quando viene chiamato SaveChanges:

-- Executed DbCommand (2ms) [Parameters=[@p1='1', @p0=NULL (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
UPDATE [Posts] SET [BlogId] = @p0
WHERE [Id] = @p1;
SELECT @@ROWCOUNT;

-- Executed DbCommand (0ms) [Parameters=[@p1='2', @p0=NULL (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
UPDATE [Posts] SET [BlogId] = @p0
WHERE [Id] = @p1;
SELECT @@ROWCOUNT;

-- Executed DbCommand (1ms) [Parameters=[@p2='1'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Blogs]
WHERE [Id] = @p2;
SELECT @@ROWCOUNT;

Analogamente, se la relazione viene interrotta usando uno degli esempi precedenti:

using var context = new BlogsContext();

var blog = await context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).FirstAsync();

foreach (var post in blog.Posts)
{
    post.Blog = null;
}

await context.SaveChangesAsync();

O:

using var context = new BlogsContext();

var blog = await context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).FirstAsync();

blog.Posts.Clear();

await context.SaveChangesAsync();

I post vengono quindi aggiornati con valori di chiave esterna Null quando viene chiamato SaveChanges:

-- Executed DbCommand (2ms) [Parameters=[@p1='1', @p0=NULL (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
UPDATE [Posts] SET [BlogId] = @p0
WHERE [Id] = @p1;
SELECT @@ROWCOUNT;

-- Executed DbCommand (0ms) [Parameters=[@p1='2', @p0=NULL (DbType = Int32)], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
UPDATE [Posts] SET [BlogId] = @p0
WHERE [Id] = @p1;
SELECT @@ROWCOUNT;

Per ulteriori informazioni su come EF Core gestisce chiavi esterne e navigazioni quando vengono modificati i loro valori, vedere Modifica di chiavi esterne e navigazioni.

Annotazioni

La correzione di relazioni come questa è il comportamento predefinito di Entity Framework dalla prima versione del 2008. Prima di EF Core non aveva un nome e non era possibile modificare. Ora è noto come ClientSetNull descritto nella sezione successiva.

I database possono anche essere configurati in modo che i valori Null a catena siano simili a questo quando un'entità o un elemento padre in una relazione facoltativa viene eliminata. Tuttavia, questo comportamento è molto meno comune rispetto all'uso di eliminazioni a catena nel database. L'uso delle eliminazioni a catena e dei valori Null a catena nel database contemporaneamente comporterà quasi sempre cicli di relazione quando si usa SQL Server. Per altre informazioni sulla configurazione di valori Null a catena, vedere la sezione successiva.

Configurazione dei comportamenti a catena

Suggerimento

Assicurarsi di leggere le sezioni precedenti prima di venire qui. È probabile che le opzioni di configurazione non abbiano senso se il materiale precedente non è compreso.

I comportamenti a catena vengono configurati per relazione usando il OnDelete metodo in OnModelCreating. Per esempio:

protected override void OnModelCreating(ModelBuilder modelBuilder)
{
    modelBuilder
        .Entity<Blog>()
        .HasOne(e => e.Owner)
        .WithOne(e => e.OwnedBlog)
        .OnDelete(DeleteBehavior.ClientCascade);
}

Per altre informazioni sulla configurazione delle relazioni tra tipi di entità, vedere Relazioni .

OnDelete accetta un valore dall'enumerazione DeleteBehavior, che è indubbiamente confusa. Questa enumerazione definisce sia il comportamento di EF Core nelle entità rilevate che la configurazione dell'eliminazione a catena nel database quando EF viene usato per creare lo schema.

Impatto sullo schema del database

Nella tabella seguente viene illustrato il risultato di ogni OnDelete valore nel vincolo di chiave esterna creato dalle migrazioni di EF Core o EnsureCreated.

DeleteBehavior Impatto sullo schema del database
Cascata ON DELETE CASCADE (alla cancellazione, elimina in cascata)
Limita ON DELETE RESTRICT
NessunaAzione database predefinito
SetNull ON DELETE SET NULL
ClientSetNull database predefinito
ClientCascade database predefinito
ClientNoAction database predefinito

I comportamenti di ON DELETE NO ACTION (impostazione predefinita del database) e ON DELETE RESTRICT nei database relazionali sono in genere identici o molto simili. Nonostante ciò che NO ACTION può implicare, entrambe queste opzioni comportano l'applicazione di vincoli referenziale. La differenza, quando ne esiste una, è quando il database controlla i vincoli. Controllare la documentazione del database per individuare le differenze specifiche tra ON DELETE NO ACTION e ON DELETE RESTRICT nel sistema di database.

SQL Server non supporta ON DELETE RESTRICT, quindi ON DELETE NO ACTION viene usato.

Gli unici valori che causeranno comportamenti a catena nel database sono Cascade e SetNull. Tutti gli altri valori configureranno il database in modo che non vengano apportate modifiche a catena.

Impatto sul comportamento di SaveChanges

Le tabelle nelle sezioni seguenti illustrano cosa accade alle entità dipendenti/figlio quando l'entità principale/padre viene eliminata o la relazione con le entità dipendenti/figlio viene interrotta. Ogni tabella copre uno dei seguenti elementi:

  • Relazioni facoltative (FK nullabile) e obbligatorie (FK non nullabile)
  • Quando dipendenti/figli vengono caricati e rilevati da DbContext e quando sono presenti solo nel database

Relazione obbligatoria con dipendenti/figli caricati

DeleteBehavior In caso di eliminazione di principale/genitore In caso di separazione da capogruppo/genitore
Cascata Dipendenti eliminati da EF Core Dipendenti eliminati da EF Core
Limita InvalidOperationException InvalidOperationException
NessunaAzione InvalidOperationException InvalidOperationException
SetNull SqlException durante la creazione di un database SqlException durante la creazione di un database
ClientSetNull InvalidOperationException InvalidOperationException
ClientCascade Dipendenti eliminati da EF Core Dipendenti eliminati da EF Core
ClientNoAction DbUpdateException InvalidOperationException

Note:

  • L'impostazione predefinita per le relazioni necessarie, come in questo caso, è Cascade.
  • L'uso di qualsiasi elemento diverso dall'eliminazione a catena per le relazioni necessarie genererà un'eccezione quando viene chiamato SaveChanges.
    • In genere, si tratta di un oggetto InvalidOperationException di EF Core perché lo stato non valido viene rilevato nei figli/dipendenti caricati.
    • ClientNoAction forza EF Core a non controllare le correzioni dipendenti prima di inviarle al database, quindi, in questo caso, il database genera un'eccezione, che viene quindi racchiusa in un DbUpdateException da SaveChanges.
    • SetNull viene respinto durante la creazione del database poiché la colonna chiave esterna non è annullabile.
  • Poiché i dipendenti a carico/figli vengono caricati, sono sempre eliminati da EF Core e non vengono mai lasciati affinché il database li elimini.

Relazione obbligatoria con dipendenti/figli non caricati

DeleteBehavior In caso di eliminazione di principale/genitore In caso di separazione da capogruppo/genitore
Cascata Dipendenti eliminati dal database Non disponibile
Limita DbUpdateException Non disponibile
NessunaAzione DbUpdateException Non disponibile
SetNull SqlException durante la creazione di un database Non disponibile
ClientSetNull DbUpdateException Non disponibile
ClientCascade DbUpdateException Non disponibile
ClientNoAction DbUpdateException Non disponibile

Note:

  • Interrompere una relazione non è applicabile qui poiché i dipendenti o i figli non sono caricati.
  • L'impostazione predefinita per le relazioni necessarie, come in questo caso, è Cascade.
  • L'uso di qualsiasi elemento diverso dall'eliminazione a catena per le relazioni necessarie genererà un'eccezione quando viene chiamato SaveChanges.
    • In genere, questo è un DbUpdateException poiché i dipendenti/figli non sono caricati, quindi lo stato invalido può essere rilevato solo dal database. SaveChanges esegue quindi il wrapping dell'eccezione del database in un oggetto DbUpdateException.
    • SetNull viene respinto durante la creazione del database poiché la colonna chiave esterna non è annullabile.

Relazione facoltativa con dipendenti/figli caricati

DeleteBehavior In caso di eliminazione di principale/genitore In caso di separazione da capogruppo/genitore
Cascata Dipendenti eliminati da EF Core Dipendenti eliminati da EF Core
Limita FK dipendenti impostati su Null da EF Core FK dipendenti impostati su Null da EF Core
NessunaAzione FK dipendenti impostati su Null da EF Core FK dipendenti impostati su Null da EF Core
SetNull FK dipendenti impostati su Null da EF Core FK dipendenti impostati su Null da EF Core
ClientSetNull FK dipendenti impostati su Null da EF Core FK dipendenti impostati su Null da EF Core
ClientCascade Dipendenti eliminati da EF Core Dipendenti eliminati da EF Core
ClienteSenzaAzione DbUpdateException FK dipendenti impostati su Null da EF Core

Note:

  • Il valore predefinito per le relazioni facoltative come questo è ClientSetNull.
  • I familiari/figli non vengono mai eliminati a meno che Cascade o ClientCascade siano configurati.
  • Tutti gli altri valori determinano l'impostazione di FK dipendenti su Null da EF Core...
    • ...tranne ClientNoAction che indica a EF Core di non modificare le chiavi esterne delle entità dipendenti/figli quando le entità principali/genitori vengono eliminate. Il database genera quindi un'eccezione, che viene gestita/incapsulata come DbUpdateException da SaveChanges.

Relazione opzionale con persone a carico/figli non caricata

DeleteBehavior In caso di eliminazione di principale/genitore In caso di separazione da capogruppo/genitore
Cascata Dipendenti eliminati dal database Non disponibile
Limita DbUpdateException Non disponibile
NessunaAzione DbUpdateException Non disponibile
SetNull FK esterni dipendenti impostati su null dal database Non disponibile
ClientSetNull DbUpdateException Non disponibile
ClientCascade DbUpdateException Non disponibile
ClientNoAction DbUpdateException Non disponibile

Note:

  • Interrompere una relazione non è applicabile qui poiché i dipendenti o i figli non sono caricati.
  • Il valore predefinito per le relazioni facoltative come questo è ClientSetNull.
  • Le persone a carico/i figli devono essere caricati per evitare un'eccezione di database, a meno che il database non sia stato configurato per effettuare eliminazioni o impostazioni a null in cascata.