Partager via


Suppression en cascade

Entity Framework Core (EF Core) représente les relations à l’aide de clés étrangères. Une entité avec une clé étrangère est l’entité enfant ou dépendante dans la relation. La valeur de clé étrangère de cette entité doit correspondre à la valeur de clé primaire (ou à une autre valeur de clé) de l’entité principale/parente associée.

Si l’entité principal/parent est supprimée, les valeurs de clé étrangère des dépendants/enfants ne correspondent plus à la clé primaire ou alternative d’un principal/parent. Il s’agit d’un état non valide et entraîne une violation de contrainte référentielle dans la plupart des bases de données.

Il existe deux options pour éviter cette violation de contrainte référentielle :

  1. Définir les valeurs du FK sur Null
  2. Supprimer également les entités dépendantes/enfants

La première option est valide uniquement pour les relations facultatives où la propriété de clé étrangère (et la colonne de base de données à laquelle elle est mappée) doit être nullable.

La deuxième option est valide pour n’importe quel type de relation et est appelée « suppression en cascade ».

Conseil / Astuce

Ce document décrit les suppressions en cascade (et la suppression des orphelins) du point de vue de la mise à jour de la base de données. Il utilise lourdement les concepts introduits dans le suivi des modifications dans EF Core et la modification des clés étrangères et des navigations. Veillez à bien comprendre ces concepts avant d’aborder le matériel ici.

Conseil / Astuce

Vous pouvez exécuter et déboguer dans tout le code de ce document en téléchargeant l’exemple de code à partir de GitHub.

Lorsque des comportements en cascade se produisent

Les suppressions en cascade sont nécessaires lorsqu’une entité dépendante/enfant ne peut plus être associée à son principal/parent actuel. Cela peut se produire parce que le principal/parent est supprimé ou qu’il peut se produire lorsque le principal/parent existe toujours, mais que le principal/l’enfant n’est plus associé à celui-ci.

Suppression d’un principal/parent

Considérez ce modèle simple où Blog est le principal/parent dans une relation avec Post, qui est le dépendant/enfant. Post.BlogId est une propriété de clé étrangère, dont la valeur doit correspondre à la Blog.Id clé primaire du blog auquel appartient le billet.

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; }
}

Par convention, cette relation est configurée comme obligatoire, car la Post.BlogId propriété de clé étrangère n’est pas nullable. Les relations requises sont configurées pour utiliser les suppressions en cascade par défaut. Pour plus d’informations sur la modélisation des relations, consultez Relations .

Lors de la suppression d’un blog, tous les billets sont supprimés en cascade. Par exemple:

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 génère le code SQL suivant, à l’aide de SQL Server comme exemple :

-- 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;

Séparation d’une relation

Au lieu de supprimer le blog, nous pourrions plutôt séparer la relation entre chaque billet et son blog. Pour ce faire, définissez la navigation Post.Blog de référence sur Null pour chaque publication :

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 relation peut également être rompue en supprimant chaque billet de la navigation dans la Blog.Posts collection :

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();

Dans les deux cas, le résultat est le même : le blog n’est pas supprimé, mais les billets qui ne sont plus associés à un blog sont supprimés :

-- 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;

La suppression d’entités qui ne sont plus associées à un principal/dépendant est appelée « suppression des orphelins ».

Conseil / Astuce

La suppression en cascade et la suppression d’orphelins sont étroitement liées. Les deux entraînent la suppression d’entités dépendantes/enfants lorsque la relation avec leur principal/parent requis est rompue. Pour la suppression en cascade, cette rupture se produit parce que le principal/parent est lui-même supprimé. Pour les orphelins, l’entité principal/parent existe toujours, mais n’est plus liée aux entités dépendantes/enfants.

Où se produisent les comportements en cascade

Les comportements en cascade peuvent être appliqués à :

  • Entités suivies actuellement par DbContext
  • Entités dans la base de données qui n’ont pas été chargées dans le contexte

Suppression en cascade d’entités suivies

EF Core applique toujours des comportements en cascade configurés aux entités suivies. Cela signifie que si l’application charge toutes les entités dépendantes/enfants pertinentes dans DbContext, comme illustré dans les exemples ci-dessus, les comportements en cascade sont appliqués correctement, quelle que soit la façon dont la base de données est configurée.

Conseil / Astuce

Le moment exact du moment où des comportements en cascade se produisent pour les entités suivies peut être contrôlé à l’aide ChangeTracker.CascadeDeleteTiming et ChangeTracker.DeleteOrphansTiming. Pour plus d’informations, consultez Modification des clés étrangères et des navigations .

Suppression en cascade dans la base de données

De nombreux systèmes de base de données offrent également des comportements en cascade qui sont déclenchés lorsqu’une entité est supprimée dans la base de données. EF Core configure ces comportements en fonction du comportement de suppression en cascade dans le modèle EF Core lorsqu’une base de données est créée à l’aide EnsureCreated ou des migrations EF Core. Par exemple, à l’aide du modèle ci-dessus, le tableau suivant est créé pour les publications lors de l’utilisation de 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
);

Notez que la contrainte de clé étrangère définissant la relation entre les blogs et les billets est configurée avec ON DELETE CASCADE.

Si nous savons que la base de données est configurée comme celle-ci, nous pouvons supprimer un blog sans d’abord charger de billets et la base de données s’occupe de supprimer tous les billets associés à ce blog. Par exemple:

using var context = new BlogsContext();

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

context.Remove(blog);

await context.SaveChangesAsync();

Notez qu’il n’y a aucun Include pour les publications, donc elles ne sont pas chargées. SaveChanges dans ce cas supprime uniquement le blog, car il s’agit de la seule entité suivie :

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

Cela entraînerait une exception si la contrainte de clé étrangère dans la base de données n’est pas configurée pour les suppressions en cascade. Toutefois, dans ce cas, les publications sont supprimées par la base de données, car elles ont été configurées ON DELETE CASCADE lors de sa création.

Remarque

Les bases de données n’ont généralement aucun moyen de supprimer automatiquement les orphelins. Cela est dû au fait que si EF Core représente des relations à l’aide de navigations ainsi que de clés étrangères, les bases de données n’ont que des clés étrangères et aucune navigation. Cela signifie qu’il n’est généralement pas possible de séparer une relation sans charger les deux côtés dans DbContext.

Remarque

La base de données EF Core en mémoire ne prend actuellement pas en charge les suppressions en cascade dans la base de données.

Avertissement

Ne configurez pas la suppression en cascade dans la base de données lors de la suppression réversible d’entités. Cela peut entraîner la suppression complète et accidentelle d’entités au lieu d'une suppression réversible.

Limitations de cascade de base de données

Certaines bases de données, notamment SQL Server, ont des limitations sur les comportements en cascade qui forment des cycles. Par exemple, considérez le modèle suivant :

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; }
}

Ce modèle a trois relations, toutes requises et donc configurées pour la suppression en cascade par convention :

  • La suppression d’un blog va en cascade supprimer tous les billets associés
  • La suppression de l’auteur de billets entraîne la suppression en cascade des publications créées
  • La suppression du propriétaire d’un blog entraîne la suppression en cascade du blog

Cela est raisonnable (si un peu draconien dans les stratégies de gestion de blog !) mais en essayant de créer une base de données SQL Server avec ces cascades configurées entraîne l’exception suivante :

Microsoft.Data.SqlClient.SqlException (0x80131904) : l’introduction de la contrainte FOREIGN KEY « FK_Posts_Person_AuthorId » sur la table « Posts » peut entraîner des cycles ou plusieurs chemins d’accès en cascade. Spécifiez ON DELETE NO ACTION ou ON UPDATE NO ACTION, ou modifiez d'autres contraintes FOREIGN KEY.

Il existe deux façons de gérer cette situation :

  1. Modifiez une ou plusieurs relations pour ne pas supprimer en cascade.
  2. Configurez la base de données sans une ou plusieurs de ces suppressions en cascade, puis vérifiez que toutes les entités dépendantes sont chargées afin qu’EF Core puisse effectuer le comportement en cascade.

En prenant la première approche avec notre exemple, nous pourrions rendre la relation post-blog facultative en lui donnant une propriété de clé étrangère nullable :

public int? BlogId { get; set; }

Une relation facultative permet au billet d’exister sans blog, ce qui signifie que la suppression en cascade ne sera plus configurée par défaut. Cela signifie qu’il n’existe plus de cycle dans les actions en cascade et que la base de données peut être créée sans erreur sur SQL Server.

En adoptant la deuxième approche à la place, nous pouvons conserver la relation de propriétaire de blog requise et configurée pour la suppression en cascade, mais rendre cette configuration s’applique uniquement aux entités suivies, et non à la base de données :

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

Que se passe-t-il si nous chargeons une personne et le blog qu’ils possèdent, puis supprimez la personne ?

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 propagera la suppression du propriétaire afin que le blog soit également supprimé.

-- 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;

Toutefois, si le blog n’est pas chargé lorsque le propriétaire est supprimé :

using var context = new BlogsContext();

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

context.Remove(owner);

await context.SaveChangesAsync();

Ensuite, une exception est levée en raison d’une violation de la contrainte de clé étrangère dans la base de données :

Microsoft.Data.SqlClient.SqlException : L’instruction DELETE est en conflit avec la contrainte REFERENCE « FK_Blogs_People_OwnerId ». Le conflit s’est produit dans la base de données « Scratch », la table « dbo.Blogs », colonne 'OwnerId'. L’instruction a été arrêtée.

Valeurs nulles en cascade

Les relations facultatives ont des propriétés de clé étrangère nullable mappées aux colonnes de base de données nullables. Cela signifie que la valeur de clé étrangère peut être définie sur null lorsque le principal/parent actuel est supprimé ou est séparé du dépendant/enfant.

Examinons à nouveau les exemples de comportements de cascade, mais cette fois avec une relation facultative représentée par une propriété de clé étrangère nullifiable :

public int? BlogId { get; set; }

Cette propriété de clé étrangère est définie sur Null pour chaque billet lorsque son blog associé est supprimé. Par exemple, ce code, qui est le même que précédemment :

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();

Génère maintenant les mises à jour de base de données suivantes lorsque SaveChanges est appelé :

-- 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;

De même, si la relation est rompue à l’aide de l’un des exemples ci-dessus :

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();

Ou:

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();

Ensuite, les messages sont mis à jour avec des valeurs de clé étrangère null lorsque SaveChanges est appelé :

-- 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;

Pour plus d’informations sur la façon dont EF Core gère les clés étrangères et les navigations à mesure que leurs valeurs sont modifiées, consultez La modification des clés étrangères et des navigations.

Remarque

La correction des relations comme celle-ci a été le comportement par défaut d’Entity Framework depuis la première version en 2008. Avant EF Core, il n’avait pas de nom et n’était pas possible de changer. Il est maintenant connu comme ClientSetNull décrit dans la section suivante.

Les bases de données peuvent également être configurées pour cascader les valeurs nulles lorsqu'une entité principale/parent dans une relation facultative est supprimée. Toutefois, cela est beaucoup moins courant que l’utilisation de suppressions en cascade dans la base de données. L’utilisation de suppressions en cascade et de valeurs null en cascade dans la base de données en même temps entraîne presque toujours des cycles de relation lors de l’utilisation de SQL Server. Pour plus d’informations sur la configuration des valeurs Null en cascade, consultez la section suivante.

Configuration des comportements en cascade

Conseil / Astuce

Veillez à lire les sections ci-dessus avant de venir ici. Les options de configuration n’auront probablement pas de sens si le matériel précédent n’est pas compris.

Les comportements en cascade sont configurés par relation à l’aide de la OnDelete méthode dans OnModelCreating. Par exemple:

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

Pour plus d’informations sur la configuration des relations entre les types d’entités, consultez Relations .

OnDelete accepte une valeur de l'énumération DeleteBehavior, certes déroutante. Cette énumération définit à la fois le comportement d’EF Core sur les entités suivies et la configuration de la suppression en cascade dans la base de données quand EF est utilisé pour créer le schéma.

Impact sur le schéma de base de données

Le tableau suivant montre le résultat de chaque OnDelete valeur sur la contrainte de clé étrangère créée par les migrations EF Core ou EnsureCreated.

DeleteBehavior Impact sur le schéma de base de données
Cascade ON DELETE CASCADE
Restreindre SUR SUPPRESSION RESTREINT (ON DELETE RESTRICT)
NoAction base de données par défaut
Définir comme nul ON DELETE SET NULL
ClientSetNull base de données par défaut
ClientCascade base de données par défaut
ClientNoAction base de données par défaut

Les comportements de ON DELETE NO ACTION (par défaut dans la base de données) et de ON DELETE RESTRICT dans les bases de données relationnelles sont généralement identiques ou très similaires. Malgré ce qui NO ACTION peut impliquer, ces deux options entraînent l’application de contraintes référentielles. La différence, lorsqu’il en existe un, est lorsque la base de données vérifie les contraintes. Consultez la documentation de votre base de données pour connaître les différences spécifiques entre ON DELETE NO ACTION et ON DELETE RESTRICT sur votre système de base de données.

SQL Server ne prend pas en charge ON DELETE RESTRICT. Il est donc ON DELETE NO ACTION utilisé à la place.

Les seules valeurs qui entraînent des comportements en cascade sur la base de données sont Cascade et SetNull. Toutes les autres valeurs configurent la base de données pour qu’elle ne modifie pas en cascade.

Impact sur le comportement de SaveChanges

Les tableaux des sections suivantes couvrent ce qui se passe pour les entités dépendantes/enfants lorsque le principal/parent est supprimé, ou sa relation avec les entités dépendantes/enfants est rompue. Chaque table couvre l’une des options suivantes :

  • Relations facultatives (FK nullables) et obligatoires (FK non nullables)
  • Lorsque les dépendants/enfants sont chargés et suivis par DbContext et lorsqu’ils existent uniquement dans la base de données

Relation requise avec les dépendants/enfants chargés

DeleteBehavior Lors de la suppression d’un principal/parent Lors de la séparation du principal/parent
Cascade Dépendants supprimés par EF Core Dépendants supprimés par EF Core
Restreindre InvalidOperationException InvalidOperationException
NoAction InvalidOperationException InvalidOperationException
Définir comme nul SqlException lors de la création d’une base de données SqlException lors de la création d’une base de données
ClientSetNull InvalidOperationException InvalidOperationException
ClientCascade Dépendants supprimés par EF Core Dépendants supprimés par EF Core
ClientNoAction DbUpdateException InvalidOperationException

Remarques :

  • La valeur par défaut pour les relations requises comme celle-ci est Cascade.
  • L’utilisation de quelque chose d’autre que la suppression en cascade pour les relations requises entraîne une exception lorsque SaveChanges est appelé.
    • En règle générale, il s'agit d'un InvalidOperationException d'EF Core, car un état invalide est détecté dans les enfants/dépendants chargés.
    • ClientNoAction force EF Core à ne pas vérifier les dépendances liées aux correctifs avant de les envoyer à la base de données, ce qui amène la base de données à générer une exception dans ce cas. Cette exception est ensuite enveloppée dans un DbUpdateException par SaveChanges.
    • SetNull est rejeté lors de la création de la base de données, car la colonne de clé étrangère n’est pas nullable.
  • Étant donné que les dépendants/enfants sont chargés, ils sont toujours supprimés par EF Core et ne sont jamais laissés à la base de données pour suppression.

Relation requise avec les dépendants/enfants non chargés

DeleteBehavior Lors de la suppression d’un principal/parent Lors de la séparation du principal/parent
Cascade Dépendants supprimés par la base de données N/A
Restreindre DbUpdateException N/A
NoAction DbUpdateException N/A
Définir comme nul SqlException lors de la création d’une base de données N/A
ClientSetNull DbUpdateException N/A
ClientCascade DbUpdateException N/A
ClientNoAction DbUpdateException N/A

Remarques :

  • La rupture d'une relation n'est pas valide ici car les dépendants/enfants ne sont pas pris en compte.
  • La valeur par défaut pour les relations requises comme celle-ci est Cascade.
  • L’utilisation de quelque chose d’autre que la suppression en cascade pour les relations requises entraîne une exception lorsque SaveChanges est appelé.
    • En règle générale, cela est dû DbUpdateException au fait que les dépendants/enfants ne sont pas chargés, et par conséquent, l’état non valide ne peut être détecté que par la base de données. SaveChanges encapsule ensuite l’exception de base de données dans un DbUpdateException.
    • SetNull est rejeté lors de la création de la base de données, car la colonne de clé étrangère n’est pas nullable.

Relation facultative avec des personnes à charge/enfants établie

DeleteBehavior Lors de la suppression d’un principal/parent Lors de la séparation du principal/parent
Cascade Dépendants supprimés par EF Core Dépendants supprimés par EF Core
Restreindre Clés FK dépendantes définies sur Null par EF Core Clés FK dépendantes définies sur Null par EF Core
NoAction Clés FK dépendantes définies sur Null par EF Core Clés FK dépendantes définies sur Null par EF Core
Définir comme nul Clés FK dépendantes définies sur Null par EF Core Clés FK dépendantes définies sur Null par EF Core
ClientSetNull Clés FK dépendantes définies sur Null par EF Core Clés FK dépendantes définies sur Null par EF Core
ClientCascade Dépendants supprimés par EF Core Dépendants supprimés par EF Core
ClientNoAction DbUpdateException Clés FK dépendantes définies sur Null par EF Core

Remarques :

  • La valeur par défaut pour les relations facultatives comme celle-ci est ClientSetNull.
  • Les personnes à charge/enfants ne sont jamais supprimé(e)s, sauf si Cascade ou ClientCascade sont configurés.
  • Toutes les autres valeurs entraînent la définition des clés FK dépendantes sur Null par EF Core...
    • ... sauf ClientNoAction ce qui indique à EF Core de ne pas toucher les clés étrangères des personnes dépendantes/enfants lorsque le principal/parent est supprimé. La base de données lève donc une exception, qui est encapsulée en tant que DbUpdateException par SaveChanges.

Relation optionnelle avec les dépendants/enfants non affichée

DeleteBehavior Lors de la suppression d’un principal/parent Lors de la séparation du principal/parent
Cascade Dépendants supprimés par la base de données N/A
Restreindre DbUpdateException N/A
NoAction DbUpdateException N/A
Définir comme nul Clés FK dépendantes définies sur Null par base de données N/A
ClientSetNull DbUpdateException N/A
ClientCascade DbUpdateException N/A
ClientNoAction DbUpdateException N/A

Remarques :

  • La rupture d'une relation n'est pas valide ici car les dépendants/enfants ne sont pas pris en compte.
  • La valeur par défaut pour les relations facultatives comme celle-ci est ClientSetNull.
  • Les dépendants/enfants doivent être chargés pour éviter une exception de base de données, sauf si la base de données a été configurée pour effectuer des suppressions ou des valeurs null en cascade.