Nota
O acesso a esta página requer autorização. Podes tentar iniciar sessão ou mudar de diretório.
O acesso a esta página requer autorização. Podes tentar mudar de diretório.
O Entity Framework Core (EF Core) representa relações usando chaves estrangeiras. Uma entidade com uma chave estrangeira é o filho ou entidade dependente na relação. O valor da chave estrangeira dessa entidade deve corresponder ao valor da chave primária (ou um valor de chave alternativa) da entidade principal/controladora relacionada.
Se a entidade principal/pai for excluída, os valores de chave estrangeira dos dependentes/filhos não corresponderão mais à chave primária ou alternativa de qualquer principal/pai. Esse é um estado inválido e causará uma violação de restrição referencial na maioria dos bancos de dados.
Há duas opções para evitar essa violação de restrição referencial:
- Definir os valores FK como nulos
- Exclua também as entidades dependentes/filhos
A primeira opção só é válida para relações opcionais em que a propriedade de chave estrangeira (e a coluna do banco de dados para a qual ela é mapeada) deve ser anulável.
A segunda opção é válida para qualquer tipo de relacionamento e é conhecida como "exclusão em cascata".
Sugestão
Este documento descreve as exclusões em cascata (e a exclusão de órfãos) da perspetiva da atualização do banco de dados. Ele faz uso intensivo de conceitos introduzidos no Rastreamento de Mudanças no EF Core e Alteração de Chaves Estrangeiras e Navegações. Certifique-se de entender completamente esses conceitos antes de abordar o material aqui.
Sugestão
Você pode executar e depurar todo o código neste documento baixando o código de exemplo do GitHub.
Quando comportamentos em cascata acontecem
As exclusões em cascata são necessárias quando uma entidade dependente/filho não pode mais ser associada ao seu principal/pai atual. Isso pode acontecer porque o principal/pai é excluído, ou pode acontecer quando o principal/pai ainda existe, mas o dependente/filho não está mais associado a ele.
Excluindo um principal/pai
Considere este modelo simples onde Blog está o principal/pai em uma relação com Post, que é o dependente/filho.
Post.BlogId é uma propriedade de chave estrangeira, cujo valor deve corresponder à Blog.Id chave primária do blog ao qual a postagem pertence.
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 convenção, essa relação é configurada como obrigatória, uma vez que a propriedade de Post.BlogId chave estrangeira não é anulável. As relações necessárias são configuradas para usar exclusões em cascata por padrão. Consulte Relações para obter mais informações sobre como modelar relações.
Ao excluir um blog, todas as postagens são excluídas em cascata. Por exemplo:
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 gera o seguinte SQL, usando o SQL Server como exemplo:
-- 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 uma relação
Em vez de excluir o blog, poderíamos cortar a relação entre cada post e seu blog. Isso pode ser feito definindo a navegação Post.Blog de referência como nula para cada postagem:
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();
A relação também pode ser cortada removendo cada postagem da navegação da Blog.Posts coleçã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();
Em ambos os casos, o resultado é o mesmo: o blog não é excluído, mas os posts que não estão mais associados a nenhum blog são excluídos:
-- 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;
A exclusão de entidades que não estão mais associadas a nenhum principal/dependente é conhecida como "exclusão de órfãos".
Sugestão
A exclusão em cascata e a exclusão de órfãos estão intimamente relacionadas. Ambos resultam na exclusão de entidades dependentes/filhas quando a relação com a sua entidade principal/pai necessária é cortada. Para a exclusão em cascata, esse corte acontece porque o principal/pai é excluído. Para órfãos, a entidade principal/mãe ainda existe, mas não está mais relacionada às entidades dependentes/filhos.
Onde os comportamentos em cascata acontecem
Os comportamentos em cascata podem ser aplicados a:
- Entidades rastreadas pelo sistema atual DbContext
- Entidades no banco de dados que não foram carregadas no contexto
Exclusão em cascata de entidades rastreadas
O EF Core sempre aplica comportamentos em cascata configurados a entidades rastreadas. Isso significa que, se o aplicativo carregar todas as entidades dependentes/filhas relevantes no DbContext, como é mostrado nos exemplos acima, os comportamentos em cascata serão aplicados corretamente, independentemente de como o banco de dados está configurado.
Sugestão
O momento exato de quando os comportamentos em cascata acontecem às entidades rastreadas pode ser controlado usando ChangeTracker.CascadeDeleteTiming e ChangeTracker.DeleteOrphansTiming. Consulte Alterando chaves estrangeiras e navegações para obter mais informações.
Exclusão em cascata no banco de dados
Muitos sistemas de banco de dados também oferecem comportamentos em cascata que são acionados quando uma entidade é excluída no banco de dados. EF Core configura esses comportamentos com base no comportamento de exclusão em cascata definido no modelo do EF Core quando um banco de dados é criado usando EnsureCreated ou migrações do EF Core. Por exemplo, usando o modelo acima, a tabela a seguir é criada para postagens ao usar o 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 a restrição de chave estrangeira que define a relação entre blogs e postagens está configurada com ON DELETE CASCADE.
Se sabemos que o banco de dados está configurado assim, então podemos excluir um blog sem primeiro carregar posts e o banco de dados se encarregará de excluir todos os posts que estavam relacionados a esse blog. Por exemplo:
using var context = new BlogsContext();
var blog = await context.Blogs.OrderBy(e => e.Name).FirstAsync();
context.Remove(blog);
await context.SaveChangesAsync();
Observe que não há Include disponível para os posts, então eles não são carregados. SaveChanges, neste caso, excluirá apenas o blog, já que essa é a única entidade que está sendo rastreada:
-- Executed DbCommand (6ms) [Parameters=[@p0='1'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Blogs]
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;
Isso resultaria em uma exceção se a restrição de chave estrangeira no banco de dados não estiver configurada para exclusões em cascata. No entanto, neste caso, as postagens são excluídas pelo banco de dados porque ele foi configurado com ON DELETE CASCADE quando foi criado.
Observação
Normalmente, os bancos de dados não têm como excluir órfãos automaticamente. Isso ocorre porque, enquanto o EF Core representa relações tanto por navegações quanto por chaves estrangeiras, os bancos de dados operam apenas com chaves estrangeiras e não têm navegações. Isso significa que geralmente não é possível cortar um relacionamento sem carregar ambos os lados no DbContext.
Observação
Atualmente, o banco de dados na memória do EF Core não oferece suporte a exclusões em cascata no banco de dados.
Advertência
Não configure a exclusão em cascata no banco de dados ao excluir entidades de forma flexível. Isso pode fazer com que as entidades sejam excluídas acidentalmente em vez de excluídas suavemente.
Limitações em cascata do banco de dados
Alguns bancos de dados, principalmente o SQL Server, têm limitações nos comportamentos em cascata que formam ciclos. Por exemplo, considere o seguinte 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 tem três relações, todas necessárias e, portanto, configuradas para exclusão em cascata por convenção:
- A exclusão de um blog excluirá em cascata todas as postagens relacionadas
- A exclusão do autor das postagens fará com que as postagens criadas sejam excluídas em cascata
- Excluir o proprietário de um blog fará com que o blog seja excluído em cascata
Tudo isso é razoável (se um pouco draconiano nas políticas de gerenciamento de blog!), mas tentar criar um banco de dados SQL Server com essas cascatas configuradas resulta na seguinte exceção:
Microsoft.Data.SqlClient.SqlException (0x80131904): Introduzir a restrição FOREIGN KEY 'FK_Posts_Person_AuthorId' na tabela 'Posts' pode causar ciclos ou vários caminhos em cascata. Especifique ON DELETE NO ACTION ou ON UPDATE NO ACTION, ou modifique outras restrições de FOREIGN KEY.
Há duas maneiras de lidar com essa situação:
- Altere uma ou mais relações para não realizar a eliminação em cascata.
- Configure o banco de dados sem uma ou mais dessas exclusões em cascata e, em seguida, certifique-se de que todas as entidades dependentes sejam carregadas para que o EF Core possa executar o comportamento em cascata.
Tomando a primeira abordagem com nosso exemplo, poderíamos tornar a relação pós-blog opcional, dando-lhe uma propriedade de chave estrangeira anulável:
public int? BlogId { get; set; }
Uma relação opcional permite que a postagem exista sem um blog, o que significa que a exclusão em cascata não será mais configurada por padrão. Isso significa que não há mais um ciclo em ações em cascata e o banco de dados pode ser criado sem erro no SQL Server.
Adotando a segunda abordagem, em vez disso, podemos manter a relação blog-proprietário necessária e configurada para exclusão em cascata, mas fazer com que essa configuração se aplique apenas a entidades rastreadas, não ao banco de dados:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<Blog>()
.HasOne(e => e.Owner)
.WithOne(e => e.OwnedBlog)
.OnDelete(DeleteBehavior.ClientCascade);
}
Agora, o que acontece se carregarmos uma pessoa e o blog que ela possui e, em seguida, excluirmos a pessoa?
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();
O EF Core fará a exclusão em cascata do proprietário para que o blog também seja excluído:
-- 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;
No entanto, se o blog não for carregado quando o proprietário for excluído:
using var context = new BlogsContext();
var owner = await context.People.SingleAsync(e => e.Name == "ajcvickers");
context.Remove(owner);
await context.SaveChangesAsync();
Em seguida, uma exceção será lançada devido à violação da restrição de chave estrangeira no banco de dados:
Microsoft.Data.SqlClient.SqlException: A instrução DELETE entrou em conflito com a restrição REFERENCE "FK_Blogs_People_OwnerId". O conflito ocorreu na base de dados "Scratch", tabela "dbo. Blogs", coluna 'OwnerId'. A instrução foi terminada.
Nulos em cascata
As relações opcionais têm propriedades de chave estrangeira anuláveis que são mapeadas para colunas anuláveis de base de dados. Isso significa que o valor da chave estrangeira pode ser definido como nulo quando o principal/pai atual é excluído ou é separado do dependente/filho.
Vejamos novamente os exemplos de Quando comportamentos em cascata acontecem, mas desta vez com uma relação opcional representada por uma propriedade de chave estrangeira anulável Post.BlogId :
public int? BlogId { get; set; }
Esta propriedade de chave estrangeira será definida como nulo para cada publicação quando o seu blog relacionado for apagado. Por exemplo, este código, que é o mesmo 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();
Irá resultar nas seguintes atualizações de base de dados quando SaveChanges for invocado.
-- 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;
Da mesma forma, se a relação for cortada usando qualquer um dos exemplos acima:
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();
Em seguida, as postagens são atualizadas com valores de chave estrangeira nulos quando SaveChanges é chamado:
-- 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 Alterando chaves estrangeiras e navegações para obter mais informações sobre como o EF Core gerencia chaves e navegações estrangeiras à medida que seus valores são alterados.
Observação
A correção de relacionamentos como esse tem sido o comportamento padrão do Entity Framework desde a primeira versão em 2008. Antes do EF Core não tinha um nome e não era possível alterar. Agora é conhecido como ClientSetNull descrito na próxima seção.
Os bancos de dados também podem ser configurados para propagar nulos desta forma quando um principal/pai em uma relação opcional é removido. No entanto, isso é muito menos comum do que usar exclusões em cascata no banco de dados. Usar exclusões em cascata e nulos em cascata no banco de dados ao mesmo tempo quase sempre resultará em ciclos de relacionamento ao usar o SQL Server. Consulte a próxima seção para obter mais informações sobre como configurar nulos em cascata.
Configurando comportamentos em cascata
Sugestão
Certifique-se de ler as seções acima antes de vir aqui. As opções de configuração provavelmente não farão sentido se o material anterior não for compreendido.
Os comportamentos em cascata são configurados por relacionamento usando o OnDelete método em OnModelCreating. Por exemplo:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<Blog>()
.HasOne(e => e.Owner)
.WithOne(e => e.OwnedBlog)
.OnDelete(DeleteBehavior.ClientCascade);
}
Consulte Relações para obter mais informações sobre como configurar relações entre tipos de entidade.
OnDelete aceita um valor do reconhecidamente confuso enum DeleteBehavior. Esse enum define o comportamento do EF Core em entidades controladas e a configuração da exclusão em cascata no banco de dados quando o EF é usado para criar o esquema.
Impacto no esquema do banco de dados
A tabela a seguir mostra o resultado de cada OnDelete valor na restrição de chave estrangeira criada pelas migrações do EF Core ou EnsureCreated.
| DeleteBehavior | Impacto no esquema do banco de dados |
|---|---|
| Cascata | EM CASCATA DE EXCLUSÃO |
| Restringir | RESTRINGIR À ELIMINAÇÃO |
| SemAção | padrão do banco de dados |
| SetNull | AO ELIMINAR, DEFINIR COMO NULO |
| ClientSetNull | padrão do banco de dados |
| ClientCascade | padrão do banco de dados |
| ClientNoAction | padrão do banco de dados |
Os comportamentos de ON DELETE NO ACTION (o padrão do banco de dados) e ON DELETE RESTRICT em bases de dados relacionais são tipicamente idênticos ou muito semelhantes. Apesar do que pode implicar, ambas as opções fazem com que as restrições referenciais NO ACTION sejam aplicadas. A diferença, quando existe, é quando o banco de dados verifica as restrições. Verifique a documentação do banco de dados para as diferenças específicas entre ON DELETE NO ACTION e ON DELETE RESTRICT no seu sistema de banco de dados.
O SQL Server não oferece suporte a ON DELETE RESTRICT, por isso ON DELETE NO ACTION é usado.
Os únicos valores que causarão comportamentos em cascata no banco de dados são Cascade e SetNull. Todos os outros valores configurarão o banco de dados para não fazer alterações em cascata.
Impacto no comportamento do SaveChanges
As tabelas nas seções a seguir cobrem o que acontece com entidades dependentes/filhos quando o principal/pai é excluído ou sua relação com as entidades dependentes/filhos é cortada. Cada quadro abrange um dos seguintes elementos:
- Relações opcionais (FK anulável) e necessárias (FK não anulável)
- Quando dependentes/filhos são carregados e rastreados pelo DbContext e quando existem apenas no banco de dados
Necessidade de estabelecer relação com os dependentes/crianças incorporados
| DeleteBehavior | Ao excluir principal/pai | Sobre a separação do principal/pai |
|---|---|---|
| Cascata | Dependentes excluídos pelo EF Core | Dependentes excluídos pelo EF Core |
| Restringir | InvalidOperationException |
InvalidOperationException |
| SemAção | InvalidOperationException |
InvalidOperationException |
| SetNull |
SqlException sobre a criação de banco de dados |
SqlException sobre a criação de banco de dados |
| ClientSetNull | InvalidOperationException |
InvalidOperationException |
| ClientCascade | Dependentes excluídos pelo EF Core | Dependentes excluídos pelo EF Core |
| ClientNoAction | DbUpdateException |
InvalidOperationException |
Observações:
- O padrão para relacionamentos necessários como este é
Cascade. - Usar algo diferente de eliminação em cascata para relações obrigatórias resultará em uma exceção quando o SaveChanges for chamado.
- Normalmente, este é um
InvalidOperationExceptiondo EF Core, uma vez que o estado inválido é detetado nos filhos/dependentes carregados. -
ClientNoActionforça o EF Core a não verificar as entidades a corrigir antes de enviá-las para o banco de dados, portanto, neste caso, o banco de dados lança uma exceção, que é então envolvida porDbUpdateExceptionatravés do SaveChanges. -
SetNullé rejeitado ao criar o banco de dados, pois a coluna de chave estrangeira não é anulável.
- Normalmente, este é um
- Como os dependentes/filhos são carregados, eles são sempre excluídos pelo EF Core e nunca são deixados para o banco de dados excluir.
Relação necessária com dependentes/filhos não foi carregada
| DeleteBehavior | Ao excluir principal/pai | Sobre a separação do principal/pai |
|---|---|---|
| Cascata | Dependentes excluídos pelo banco de dados | N/A |
| Restringir | DbUpdateException |
N/A |
| SemAção | DbUpdateException |
N/A |
| SetNull |
SqlException sobre a criação de banco de dados |
N/A |
| ClientSetNull | DbUpdateException |
N/A |
| ClientCascade | DbUpdateException |
N/A |
| ClientNoAction | DbUpdateException |
N/A |
Observações:
- Romper uma relação não é válido aqui, uma vez que os dependentes/filhos não são carregados.
- O padrão para relacionamentos necessários como este é
Cascade. - Usar algo diferente de eliminação em cascata para relações obrigatórias resultará em uma exceção quando o SaveChanges for chamado.
- Normalmente, isso ocorre
DbUpdateExceptionporque os dependentes/filhos não são carregados e, portanto, o estado inválido só pode ser detetado pelo banco de dados. SaveChanges encapsula a exceção de base de dados em umDbUpdateException. -
SetNullé rejeitado ao criar o banco de dados, pois a coluna de chave estrangeira não é anulável.
- Normalmente, isso ocorre
Relação opcional com dependentes/filhos carregados
| DeleteBehavior | Ao excluir principal/pai | Sobre a separação do principal/pai |
|---|---|---|
| Cascata | Dependentes excluídos pelo EF Core | Dependentes excluídos pelo EF Core |
| Restringir | FKs dependentes configuradas para nulas pelo EF Core | FKs dependentes configuradas para nulas pelo EF Core |
| SemAção | FKs dependentes configuradas para nulas pelo EF Core | FKs dependentes configuradas para nulas pelo EF Core |
| SetNull | FKs dependentes configuradas para nulas pelo EF Core | FKs dependentes configuradas para nulas pelo EF Core |
| ClientSetNull | FKs dependentes configuradas para nulas pelo EF Core | FKs dependentes configuradas para nulas pelo EF Core |
| ClientCascade | Dependentes excluídos pelo EF Core | Dependentes excluídos pelo EF Core |
| ClientNoAction | DbUpdateException |
FKs dependentes configuradas para nulas pelo EF Core |
Observações:
- O padrão para relações opcionais como esta é
ClientSetNull. - Os dependentes/filhos nunca são excluídos, a menos que
CascadeouClientCascadeestejam configurados. - Todos os outros valores fazem com que os FKs dependentes sejam definidos como nulos pelo EF Core...
- ... exceto
ClientNoActionque instrui o EF Core para não tocar nas chaves estrangeiras de dependentes/filhos quando a entidade principal/pai é eliminada. O banco de dados, portanto, lança uma exceção, que é encapsulada como umDbUpdateExceptionpor SaveChanges.
- ... exceto
Relação opcional com dependentes/filhos não carregados
| DeleteBehavior | Ao excluir principal/pai | Sobre a separação do principal/pai |
|---|---|---|
| Cascata | Dependentes excluídos pelo banco de dados | N/A |
| Restringir | DbUpdateException |
N/A |
| SemAção | DbUpdateException |
N/A |
| SetNull | FKs dependentes definidos como nulos pela base de dados | N/A |
| ClientSetNull | DbUpdateException |
N/A |
| ClientCascade | DbUpdateException |
N/A |
| ClientNoAction | DbUpdateException |
N/A |
Observações:
- Romper uma relação não é válido aqui, uma vez que os dependentes/filhos não são carregados.
- O padrão para relações opcionais como esta é
ClientSetNull. - Os dependentes/filhos devem ser carregados para evitar uma exceção de banco de dados, a menos que o banco de dados tenha sido configurado para excluir ou anular em cascata.