Compartir a través de


Eliminación automática en cascada

Entity Framework Core (EF Core) representa relaciones mediante claves externas. Una entidad con una clave externa es la entidad hija o dependiente en la relación. El valor de clave externa de esta entidad debe coincidir con el valor de clave principal (o un valor de clave alternativa) de la entidad principal o primaria relacionada.

Si se elimina la entidad principal o primaria, los valores de clave externa de los dependientes o hijos ya no coincidirán con la clave primaria o alternativa de cualquier entidad principal o padre. Se trata de un estado no válido y provocará una infracción de restricción referencial en la mayoría de las bases de datos.

Hay dos opciones para evitar esta infracción de restricción referencial:

  1. Establezca los valores de FK en NULL.
  2. Elimine también las entidades dependientes o secundarias.

La primera opción solo es válida para las relaciones opcionales en las que la propiedad de clave externa (y la columna de base de datos a la que están asignadas) deben admitir valores nulos.

La segunda opción es válida para cualquier tipo de relación y se conoce como "eliminación en cascada".

Sugerencia

En este documento se describen las eliminaciones en cascada (y la eliminación de huérfanos) desde la perspectiva de actualizar la base de datos. Hace un uso intensivo de los conceptos introducidos en Seguimiento de cambios en EF Core y Cambio de claves foráneas y referencias. Asegúrese de comprender completamente estos conceptos antes de abordar el material aquí.

Sugerencia

Puede ejecutar y depurar todo el código de este documento descargando el código de ejemplo de GitHub.

Cuando se producen comportamientos en cascada

Las eliminaciones en cascada son necesarias cuando ya no se puede asociar una entidad dependiente o secundaria a su entidad principal o primaria actual. Esto puede ocurrir porque se elimina el principal/padre, o puede ocurrir cuando el principal/padre todavía existe, pero el dependiente/hijo ya no está asociado a él.

Eliminación de una entidad principal o elemento padre

Tenga en cuenta este modelo simple, donde Blog es el principal/padre en una relación con Post, que es el dependiente/hijo. Post.BlogId es una propiedad de clave externa, cuyo valor debe coincidir con la Blog.Id clave principal del blog al que pertenece la entrada.

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

Por convención, esta relación se configura como obligatoria, ya que la Post.BlogId propiedad de clave externa no acepta valores NULL. Las relaciones necesarias están configuradas para usar eliminaciones en cascada de forma predeterminada. Consulte Relaciones para obtener más información sobre el modelado de relaciones.

Al eliminar un blog, todas las entradas se eliminan en cascada. Por ejemplo:

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 el siguiente código SQL mediante SQL Server como ejemplo:

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

Romper una relación

En lugar de eliminar el blog, podríamos en su lugar romper la relación entre cada entrada y su blog. Para ello, establezca la navegación Post.Blog de referencia en NULL para cada publicación:

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 relación también se puede romper quitando cada publicación de la navegación de la Blog.Posts colección:

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

En cualquier caso, el resultado es el mismo: el blog no se elimina, pero las entradas que ya no están asociadas a ningún blog se eliminan:

-- 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 eliminación de entidades que ya no están asociadas a ningún principal/dependiente se conoce como "eliminar huérfanos".

Sugerencia

La eliminación en cascada y la eliminación de huérfanos están estrechamente relacionadas. Ambos dan lugar a la eliminación de entidades dependientes o secundarias cuando se rompe la relación con su entidad principal o primaria requerida. Para la eliminación en cascada, esta separación se produce porque la entidad principal o padre se elimina. En el caso de los huérfanos, la entidad principal o primaria sigue existiendo, pero ya no está relacionada con las entidades dependientes o secundarias.

Dónde se producen comportamientos en cascada

Los comportamientos en cascada se pueden aplicar a:

  • Entidades de las que realiza el seguimiento actual DbContext
  • Entidades de la base de datos que no se han cargado en el contexto

Eliminación en cascada de entidades con seguimiento

EF Core siempre aplica comportamientos en cascada configurados a entidades de seguimiento. Esto significa que si la aplicación carga todas las entidades dependientes o secundarias pertinentes en DbContext, como se muestra en los ejemplos anteriores, los comportamientos en cascada se aplicarán correctamente independientemente de cómo se configure la base de datos.

Sugerencia

El tiempo exacto de cuándo se producen comportamientos en cascada para las entidades de seguimiento se puede controlar mediante ChangeTracker.CascadeDeleteTiming y ChangeTracker.DeleteOrphansTiming. Consulte Cambio de claves externas y navegación para obtener más información.

Eliminación en cascada en la base de datos

Muchos sistemas de base de datos también ofrecen comportamientos en cascada que se desencadenan cuando se elimina una entidad en la base de datos. EF Core configura estos comportamientos en función del comportamiento de eliminación en cascada en el modelo de EF Core cuando se crea una base de datos mediante EnsureCreated o migraciones de EF Core. Por ejemplo, con el modelo anterior, se crea la tabla siguiente para publicaciones cuando se 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
);

Observe que la restricción de clave externa que define la relación entre blogs y publicaciones está configurada con ON DELETE CASCADE.

Si sabemos que la base de datos está configurada de esta manera, podemos eliminar un blog sin cargar primero las entradas y la base de datos se encargará de eliminar todas las publicaciones relacionadas con ese blog. Por ejemplo:

using var context = new BlogsContext();

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

context.Remove(blog);

await context.SaveChangesAsync();

Observe que no hay ninguna Include para las publicaciones, por lo que no se cargan. SaveChanges en este caso eliminará solo el blog, ya que es la única entidad a la que se realiza el seguimiento:

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

Esto provocaría una excepción si la restricción de clave externa de la base de datos no está configurada para eliminaciones en cascada. Sin embargo, en este caso, la base de datos elimina las publicaciones porque se ha configurado con ON DELETE CASCADE cuando se creó.

Nota:

Las bases de datos no suelen tener ninguna manera de eliminar automáticamente huérfanos. Esto se debe a que, mientras EF Core representa las relaciones mediante navegaciones y llaves foráneas, las bases de datos solo tienen llaves foráneas y ninguna navegación. Esto significa que normalmente no es posible interrumpir una relación sin cargar ambos lados en DbContext.

Nota:

La base de datos en memoria de EF Core no admite actualmente eliminaciones en cascada en la base de datos.

Advertencia

No configure la eliminación en cascada en la base de datos al eliminar entidades temporalmente. Esto puede hacer que las entidades se eliminen accidentalmente en lugar de eliminarse temporalmente.

Limitaciones de la cascada de bases de datos

Algunas bases de datos, en particular SQL Server, tienen limitaciones en los comportamientos en cascada que forman ciclos. Por ejemplo, considere el siguiente modelo:

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

Este modelo tiene tres relaciones, todas las necesarias y, por lo tanto, configuradas para eliminar en cascada por convención:

  • La eliminación de un blog eliminará en cascada todas las entradas relacionadas.
  • Eliminar el autor de las publicaciones hará que las publicaciones creadas se eliminen en cascada.
  • La eliminación del propietario de un blog hará que el blog se elimine en cascada.

Esto es todo razonable (si un poco draconiano en las directivas de administración de blog!) pero intenta crear una base de datos de SQL Server con estas cascadas configuradas da como resultado la siguiente excepción:

Microsoft.Data.SqlClient.SqlException (0x80131904): Introducir la restricción FOREIGN KEY "FK_Posts_Person_AuthorId" en la tabla "Posts" puede provocar ciclos o varias rutas de acceso en cascada. Especifique ON DELETE NO ACTION o UPDATE NO ACTION, o bien modifique otras restricciones FOREIGN KEY.

Hay dos maneras de controlar esta situación:

  1. Cambie una o varias de las relaciones para no eliminar en cascada.
  2. Configure la base de datos sin una o varias de estas eliminaciones en cascada y asegúrese de que todas las entidades dependientes se carguen para que EF Core pueda realizar el comportamiento en cascada.

Tomando el primer enfoque con nuestro ejemplo, podríamos hacer que la relación posterior al blog sea opcional al proporcionarle una propiedad de clave externa que acepta valores NULL:

public int? BlogId { get; set; }

Una relación opcional permite que la publicación exista sin un blog, lo que significa que la eliminación en cascada ya no se configurará de forma predeterminada. Esto significa que ya no hay un ciclo en acciones en cascada y la base de datos se puede crear sin errores en SQL Server.

Tomando en su lugar el segundo enfoque, podemos mantener la relación del propietario del blog necesaria y configurada para la eliminación en cascada, pero hacer que esta configuración solo se aplique a entidades de seguimiento, no a la base de datos:

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

Ahora, ¿qué ocurre si cargamos tanto una persona como el blog que poseen, entonces eliminamos a 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 aplicará en cascada la eliminación del propietario para que también se elimine el blog:

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

Sin embargo, si el blog no se carga al eliminarse el propietario:

using var context = new BlogsContext();

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

context.Remove(owner);

await context.SaveChangesAsync();

A continuación, se producirá una excepción debido a la infracción de la restricción de clave externa en la base de datos:

Microsoft.Data.SqlClient.SqlException: la instrucción DELETE entra en conflicto con la restricción REFERENCE "FK_Blogs_People_OwnerId". El conflicto se produjo en la base de datos "Scratch", tabla "dbo. Blogs", columna "OwnerId". Se terminó la declaración.

Valores NULL en cascada

Las relaciones opcionales tienen propiedades de clave externa que pueden contener valores nulos, asignadas a columnas de base de datos que también pueden contener valores nulos. Esto significa que el valor de clave externa se puede establecer en null cuando se elimina el principal o padre actual o se separa del dependiente o hijo.

Veamos de nuevo los ejemplos de Cuando se producen comportamientos en cascada, pero esta vez con una relación opcional representada por una propiedad de clave externa que acepta Post.BlogId valores NULL:

public int? BlogId { get; set; }

Esta propiedad de clave externa se establecerá en NULL para cada entrada cuando se elimine su blog relacionado. Por ejemplo, este código, que es el mismo que antes:

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

Ahora se producirán las siguientes actualizaciones de base de datos cuando se llame a 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;

Del mismo modo, si la relación se separa mediante cualquiera de los ejemplos anteriores:

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

A continuación, las publicaciones se actualizan con valores de clave externa NULL cuando se llama a 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;

Consulte Cambio de claves externas y navegaciones para obtener más información sobre cómo EF Core administra las claves externas y las navegaciones a medida que cambian sus valores.

Nota:

La corrección de relaciones como esta ha sido el comportamiento predeterminado de Entity Framework desde la primera versión en 2008. Antes de EF Core no tenía un nombre y no era posible cambiar. Ahora se conoce como ClientSetNull, tal como se describe en la sección siguiente.

Las bases de datos también se pueden configurar para propagar valores NULL en cascada, como cuando se elimina un principal/padre en una relación opcional. Sin embargo, esto es mucho menos común que usar eliminaciones en cascada en la base de datos. El uso de eliminaciones en cascada y de valores NULL en cascada en la base de datos al mismo tiempo casi siempre resultará en ciclos en las relaciones al usar SQL Server. Consulte la sección siguiente para obtener más información sobre cómo configurar valores NULL en cascada.

Configuración de comportamientos en cascada

Sugerencia

Asegúrese de leer las secciones anteriores antes de venir aquí. Es probable que las opciones de configuración no tengan sentido si no se entiende el material anterior.

Los comportamientos en cascada se configuran por relación mediante el OnDelete método en OnModelCreating. Por ejemplo:

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

Consulte Relaciones para obtener más información sobre cómo configurar relaciones entre tipos de entidad.

OnDelete acepta un valor de la enumeración, ciertamente confusa DeleteBehavior . Esta enumeración define tanto el comportamiento de EF Core en entidades de seguimiento como la configuración de eliminación en cascada en la base de datos cuando se usa EF para crear el esquema.

Impacto en el esquema de la base de datos

En la tabla siguiente se muestra el resultado para cada valor de OnDelete en la restricción de clave foránea creada por migraciones de EF Core o EnsureCreated.

DeleteBehavior Impacto en el esquema de la base de datos
Cascada AL ELIMINAR EN CASCADA
Restringir En caso de eliminación, aplicar restricción
SinAcción valor predeterminado de la base de datos
EstablecerNulo ON DELETE SET NULL
ClientSetNull valor predeterminado de la base de datos
ClientCascade valor predeterminado de la base de datos
ClientNoAction valor predeterminado de la base de datos

Los comportamientos de ON DELETE NO ACTION (el valor predeterminado de la base de datos) y de ON DELETE RESTRICT en las bases de datos relacionales suelen ser idénticos o muy similares. A pesar de lo que NO ACTION puede implicar, ambas opciones hacen que se apliquen restricciones referenciales. La diferencia, cuando hay una, es cuando la base de datos comprueba las restricciones. Compruebe la documentación de la base de datos para conocer las diferencias específicas entre ON DELETE NO ACTION y ON DELETE RESTRICT en el sistema de base de datos.

SQL Server no admite ON DELETE RESTRICT, por lo que ON DELETE NO ACTION se usa en su lugar.

Los únicos valores que provocarán comportamientos en cascada en la base de datos son Cascade y SetNull. Todos los demás valores configurarán la base de datos para que no realice ningún cambio en cascada.

Impacto en el comportamiento de SaveChanges

Las tablas de las secciones siguientes abordan lo que sucede con las entidades dependientes o secundarias cuando se eliminan las entidades principales, o cuando su relación con las entidades dependientes o secundarias se interrumpe. Cada tabla cubre una de las siguientes opciones:

  • Relaciones opcionales de FK (FK que acepta valores NULL) y relaciones necesarias de FK (FK que no acepta valores NULL)
  • Cuando el DbContext carga y sigue a los hijos o dependientes y cuando solo existen en la base de datos.

Relación necesaria con dependientes/niños cargada

DeleteBehavior Al eliminar el principal/padre Al separarse de la entidad principal/matriz
Cascada Dependientes eliminados por EF Core Dependientes eliminados por EF Core
Restringir InvalidOperationException InvalidOperationException
SinAcción InvalidOperationException InvalidOperationException
EstablecerNulo SqlException al crear una base de datos SqlException al crear una base de datos
ClientSetNull InvalidOperationException InvalidOperationException
ClientCascade Dependientes eliminados por EF Core Dependientes eliminados por EF Core
ClientNoAction DbUpdateException InvalidOperationException

Notas:

  • El valor predeterminado para las relaciones necesarias como esta es Cascade.
  • El uso de cualquier cosa que no sea la eliminación en cascada para las relaciones necesarias producirá una excepción cuando se llame a SaveChanges.
    • Normalmente, se trata de un InvalidOperationException de EF Core, ya que el estado no válido se detecta en los elementos secundarios o dependientes cargados.
    • ClientNoAction obliga a EF Core a no verificar la corrección de las dependencias antes de enviarlas a la base de datos, por lo que, en este caso, la base de datos lanza una excepción, que luego es envuelta en un DbUpdateException por SaveChanges.
    • SetNull se rechaza al crear la base de datos, ya que la columna de clave externa no admite valores NULL.
  • Dado que los dependientes o secundarios son cargados, EF Core siempre los elimina y nunca deja que la base de datos los elimine.

Relación requerida con dependientes/niños no cargada

DeleteBehavior Al eliminar el principal/padre Al separarse de la entidad principal/matriz
Cascada Dependientes eliminados por base de datos No disponible
Restringir DbUpdateException No disponible
SinAcción DbUpdateException No disponible
EstablecerNulo SqlException al crear una base de datos No disponible
ClientSetNull DbUpdateException No disponible
ClientCascade DbUpdateException No disponible
ClientNoAction DbUpdateException No disponible

Notas:

  • Romper una relación no es válido aquí, ya que no se cargan los dependientes/niños.
  • El valor predeterminado para las relaciones necesarias como esta es Cascade.
  • El uso de cualquier cosa que no sea la eliminación en cascada para las relaciones necesarias producirá una excepción cuando se llame a SaveChanges.
    • Normalmente, este es un DbUpdateException debido a que los dependientes o niños no se cargan y, por tanto, el estado no válido solo puede ser detectado por la base de datos. A continuación, SaveChanges envuelve la excepción de la base de datos en un DbUpdateException.
    • SetNull se rechaza al crear la base de datos, ya que la columna de clave externa no admite valores NULL.

Relación opcional con dependientes/niños cargada

DeleteBehavior Al eliminar el principal/padre Al separarse de la entidad principal/matriz
Cascada Dependientes eliminados por EF Core Dependientes eliminados por EF Core
Restringir FKs dependientes se establecen en nulo por medio de EF Core FKs dependientes se establecen en nulo por medio de EF Core
SinAcción FKs dependientes se establecen en nulo por medio de EF Core FKs dependientes se establecen en nulo por medio de EF Core
EstablecerNulo FKs dependientes se establecen en nulo por medio de EF Core FKs dependientes se establecen en nulo por medio de EF Core
ClientSetNull FKs dependientes se establecen en nulo por medio de EF Core FKs dependientes se establecen en nulo por medio de EF Core
ClientCascade Dependientes eliminados por EF Core Dependientes eliminados por EF Core
ClientNoAction DbUpdateException FKs dependientes se establecen en nulo por medio de EF Core

Notas:

  • El valor predeterminado para las relaciones opcionales como esta es ClientSetNull.
  • Los dependientes/hijos nunca se eliminan a menos que Cascade o ClientCascade estén configurados.
  • Todos los demás valores hacen que los FK dependientes se establezcan en NULL por EF Core...
    • ... excepto ClientNoAction que indica a EF Core que no toque las claves externas de elementos dependientes o hijos cuando se elimine el principal o el padre. Por lo tanto, la base de datos lanza una excepción, que es manejada como un DbUpdateException por SaveChanges.

Relación opcional con dependientes/hijos no cargados

DeleteBehavior Al eliminar el principal/padre Al separarse de la entidad principal/matriz
Cascada Dependientes eliminados por base de datos No disponible
Restringir DbUpdateException No disponible
SinAcción DbUpdateException No disponible
EstablecerNulo FK dependientes establecidos en NULL por base de datos No disponible
ClientSetNull DbUpdateException No disponible
ClientCascade DbUpdateException No disponible
ClientNoAction DbUpdateException No disponible

Notas:

  • Romper una relación no es válido aquí, ya que no se cargan los dependientes/niños.
  • El valor predeterminado para las relaciones opcionales como esta es ClientSetNull.
  • Los elementos dependientes o secundarios deben cargarse para evitar una excepción de base de datos a menos que la base de datos se haya configurado para eliminar en cascada o valores NULL.