Kaskádové odstranění
Entity Framework Core (EF Core) představuje relace pomocí cizích klíčů. Entita s cizím klíčem je podřízená nebo závislá entita v relaci. Hodnota cizího klíče této entity musí odpovídat hodnotě primárního klíče (nebo alternativní hodnotě klíče) souvisejícího objektu zabezpečení nebo nadřazené entity.
Pokud je objekt zabezpečení nebo nadřazená entita odstraněna, hodnoty cizího klíče závislých/podřízených objektů již nebudou odpovídat primárnímu nebo alternativnímu klíči objektu zabezpečení nebo nadřazeného objektu. Toto je neplatný stav a ve většině databází způsobí porušení referenčního omezení.
Existují dvě možnosti, jak se vyhnout tomuto porušení referenčního omezení:
- Nastavení hodnot FK na hodnotu null
- Odstraňte také závislé nebo podřízené entity.
První možnost je platná pouze pro volitelné relace, kde vlastnost cizího klíče (a sloupec databáze, na který je mapován), musí být nullable.
Druhá možnost je platná pro jakýkoli druh relace a označuje se jako kaskádové odstranění.
Tip
Tento dokument popisuje kaskádové odstranění (a odstranění osamocených) z pohledu aktualizace databáze. Využívá velké využití konceptů zavedených ve službě Change Tracking v EF Core a změně cizích klíčů a navigace. Před řešením tohoto materiálu se ujistěte, že tyto koncepty plně rozumíte.
Tip
Celý kód v tomto dokumentu můžete spustit a ladit tak, že si stáhnete ukázkový kód z GitHubu.
Při kaskádových chováních dochází
Kaskádové odstranění jsou potřeba v případě, že závislá/podřízená entita již nemůže být přidružena k aktuálnímu objektu zabezpečení nebo nadřazenosti. K tomu může dojít, protože objekt zabezpečení nebo nadřazený objekt je odstraněný nebo k němu může dojít, když objekt zabezpečení nebo nadřazený objekt stále existuje, ale závislý/podřízený objekt už k němu není přidružený.
Odstranění objektu zabezpečení nebo nadřazeného objektu
Vezměte v úvahu tento jednoduchý model, kde Blog
je objekt zabezpečení nebo nadřazený objekt ve vztahu se závislým/podřízeným objektem Post
. Post.BlogId
je vlastnost cizího klíče, jehož hodnota musí odpovídat Blog.Id
primárnímu klíči blogu, ke kterému příspěvek patří.
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; }
}
Podle konvence je tato relace nakonfigurována jako povinná, protože vlastnost cizího Post.BlogId
klíče není nullable. Požadované relace jsou nakonfigurované tak, aby ve výchozím nastavení používaly kaskádové odstranění. Další informace o relacích modelování najdete v tématu Relace .
Při odstraňování blogu se odstraní všechny příspěvky. Příklad:
using var context = new BlogsContext();
var blog = context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).First();
context.Remove(blog);
context.SaveChanges();
Funkce SaveChanges vygeneruje následující SQL pomocí SQL Serveru jako příklad:
-- 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;
Dělení relace
Místo odstranění blogu bychom místo toho mohli oddělit vztah mezi jednotlivými příspěvky a jeho blogem. To lze provést nastavením referenční navigace Post.Blog
na hodnotu null pro každý příspěvek:
using var context = new BlogsContext();
var blog = context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).First();
foreach (var post in blog.Posts)
{
post.Blog = null;
}
context.SaveChanges();
Vztah může být také přerušen odebráním každého příspěvku Blog.Posts
z navigace kolekce:
using var context = new BlogsContext();
var blog = context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).First();
blog.Posts.Clear();
context.SaveChanges();
V obou případech je výsledek stejný: blog se neodstraní, ale příspěvky, které už nejsou přidružené k žádnému blogu, se odstraní:
-- 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;
Odstranění entit, které už nejsou přidružené k žádnému objektu zabezpečení nebo závislému objektu, se označuje jako "odstranění osamocených objektů".
Tip
Kaskádové odstranění a odstranění osamocených objektů úzce souvisí. Oba mají za následek odstranění závislých/podřízených entit, pokud je vztah k požadovanému objektu zabezpečení nebo nadřazenosti přerušen. V případě kaskádového odstranění dojde k tomuto dělení, protože se odstraní objekt zabezpečení nebo nadřazený objekt. U osamocených objektů stále existuje objekt zabezpečení nebo nadřazená entita, ale už nesouvisí se závislými/podřízenými entitami.
Kde dochází k kaskádové chování
Kaskádové chování lze použít na:
- Entity sledované aktuálním DbContext
- Entity v databázi, které nebyly načteny do kontextu
Kaskádové odstranění sledovaných entit
EF Core vždy používá nakonfigurované kaskádové chování pro sledované entity. To znamená, že pokud aplikace načte všechny relevantní závislé/podřízené entity do DbContext, jak je znázorněno v příkladech výše, kaskádové chování se použije správně bez ohledu na to, jak je databáze nakonfigurovaná.
Tip
Přesné načasování, kdy se kaskádové chování děje se sledovanými entitami, lze řídit pomocí ChangeTracker.CascadeDeleteTiming a ChangeTracker.DeleteOrphansTiming. Další informace najdete v tématu Změna cizích klíčů a navigace.
Kaskádové odstranění v databázi
Mnoho databázových systémů také nabízí kaskádové chování, které se aktivuje při odstranění entity v databázi. EF Core toto chování konfiguruje na základě kaskádového chování odstranění v modelu EF Core při vytvoření databáze pomocí EnsureCreated migrace EF Core nebo EF Core. Například pomocí výše uvedeného modelu se pro příspěvky při použití SQL Serveru vytvoří následující tabulka:
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
);
Všimněte si, že omezení cizího klíče definující vztah mezi blogy a příspěvky je nakonfigurováno s ON DELETE CASCADE
.
Pokud víme, že je databáze nakonfigurovaná takto, můžeme odstranit blog bez prvního načtení příspěvků a databáze se postará o odstranění všech příspěvků souvisejících s tímto blogem. Příklad:
using var context = new BlogsContext();
var blog = context.Blogs.OrderBy(e => e.Name).First();
context.Remove(blog);
context.SaveChanges();
Všimněte si, že pro příspěvky nejsou žádné Include
, takže se nenačtou. SaveChanges v tomto případě odstraní jenom blog, protože se jedná o jedinou sledovaný entitu:
-- Executed DbCommand (6ms) [Parameters=[@p0='1'], CommandType='Text', CommandTimeout='30']
SET NOCOUNT ON;
DELETE FROM [Blogs]
WHERE [Id] = @p0;
SELECT @@ROWCOUNT;
To by vedlo k výjimce v případě, že omezení cizího klíče v databázi není nakonfigurováno pro kaskádové odstranění. V tomto případě však databáze příspěvky odstraní, protože byla nakonfigurována ON DELETE CASCADE
při jeho vytvoření.
Poznámka:
Databáze obvykle nemají žádný způsob, jak automaticky odstranit osamocené osamocené. Je to proto, že zatímco EF Core představuje relace pomocí navigace i cizích klíčů, databáze mají pouze cizí klíče a žádné navigace. To znamená, že obvykle není možné oddělit relaci bez načtení obou stran do DbContext.
Poznámka:
Databáze EF Core v paměti v současné době nepodporuje kaskádové odstranění v databázi.
Upozorňující
Při obnovitelném odstranění entit nekonfigurujte kaskádové odstranění v databázi. To může způsobit, že se entity omylem odstraní místo obnovitelného odstranění.
Omezení kaskádové databáze
Některé databáze, zejména SQL Server, mají omezení kaskádového chování, která tvoří cykly. Představte si například následující model:
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; }
}
Tento model má tři relace, všechny požadované a nakonfigurované pro kaskádové odstranění podle konvence:
- Odstranění blogu kaskádně odstraní všechny související příspěvky.
- Odstranění autora příspěvků způsobí kaskádové odstranění vytvořených příspěvků.
- Odstranění vlastníka blogu způsobí kaskádové odstranění blogu.
To je všechno rozumné (pokud je trochu drakonian v zásadách správy blogů!), ale pokus o vytvoření databáze SQL Serveru s těmito kaskádovými nakonfigurovanými výsledky způsobí následující výjimku:
Microsoft.Data.SqlClient.SqlException (0x80131904): Představujeme omezení CIZÍHO KLÍČE FK_Posts_Person_AuthorId v tabulce Příspěvky může způsobit cykly nebo více kaskádových cest. Zadejte ON DELETE NO ACTION nebo ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
Existují dva způsoby, jak tuto situaci vyřešit:
- Změňte jednu nebo více relací tak, aby se kaskádové odstranění neodstranily.
- Nakonfigurujte databázi bez jednoho nebo několika těchto kaskádových odstranění a pak zajistěte, aby všechny závislé entity byly načteny, aby EF Core mohl provádět kaskádové chování.
Při prvním přístupu v našem příkladu bychom mohli vztah post-blog nepovinný tím, že mu poskytneme vlastnost cizího klíče s možnou hodnotou null:
public int? BlogId { get; set; }
Volitelný vztah umožňuje, aby příspěvek existoval bez blogu, což znamená, že kaskádové odstranění už nebude ve výchozím nastavení nakonfigurované. To znamená, že v kaskádových akcích už neexistuje cyklus a databáze se dá vytvořit bez chyby na SQL Serveru.
Když použijeme druhý přístup, můžeme zachovat požadovaný vztah vlastníka blogu a nakonfigurovat pro kaskádové odstranění, ale tuto konfiguraci použít pouze pro sledované entity, ne pro databázi:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<Blog>()
.HasOne(e => e.Owner)
.WithOne(e => e.OwnedBlog)
.OnDelete(DeleteBehavior.ClientCascade);
}
Co se stane, když načteme osobu i blog, který vlastní, a pak osobu odstraníme?
using var context = new BlogsContext();
var owner = context.People.Single(e => e.Name == "ajcvickers");
var blog = context.Blogs.Single(e => e.Owner == owner);
context.Remove(owner);
context.SaveChanges();
EF Core bude kaskádovat odstranění vlastníka, aby se blog odstranil také:
-- 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;
Pokud se ale blog při odstranění vlastníka nenačte:
using var context = new BlogsContext();
var owner = context.People.Single(e => e.Name == "ajcvickers");
context.Remove(owner);
context.SaveChanges();
Pak dojde k výjimce z důvodu porušení omezení cizího klíče v databázi:
Microsoft.Data.SqlClient.SqlException: Příkaz DELETE byl v konfliktu s omezením REFERENCE "FK_Blogs_Lidé_OwnerId". Došlo ke konfliktu v databázi "Scratch", tabulka "dbo. Blogy", sloupec OwnerId. Příkaz byl ukončen.
Kaskádové hodnoty null
Volitelné relace mají vlastnosti cizího klíče s možnou hodnotou null namapované na sloupce databáze s možnou hodnotou null. To znamená, že hodnota cizího klíče může být nastavena na hodnotu null při odstranění aktuálního objektu zabezpečení nebo nadřazeného objektu nebo jeho odstranění ze závislé/podřízené položky.
Pojďme se znovu podívat na příklady z při kaskádovém chování, ale tentokrát s volitelnou relací reprezentovanou vlastností cizího klíče s možnou Post.BlogId
hodnotou null:
public int? BlogId { get; set; }
Tato vlastnost cizího klíče bude nastavena na hodnotu null pro každý příspěvek při odstranění souvisejícího blogu. Například tento kód, který je stejný jako předtím:
using var context = new BlogsContext();
var blog = context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).First();
context.Remove(blog);
context.SaveChanges();
Výsledkem budou nyní následující aktualizace databáze při zavolání 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;
Podobně platí, že pokud je vztah přerušen pomocí některého z výše uvedených příkladů:
using var context = new BlogsContext();
var blog = context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).First();
foreach (var post in blog.Posts)
{
post.Blog = null;
}
context.SaveChanges();
Nebo:
using var context = new BlogsContext();
var blog = context.Blogs.OrderBy(e => e.Name).Include(e => e.Posts).First();
blog.Posts.Clear();
context.SaveChanges();
Potom se příspěvky aktualizují o hodnoty cizího klíče null při zavolání 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;
Další informace o tom, jak EF Core spravuje cizí klíče a navigace při změně jejich hodnot, najdete v tématu Změna cizích klíčů a navigace.
Poznámka:
Oprava relací, jako je tato, byla výchozím chováním entity Framework od první verze v roce 2008. Před EF Core neměl název a nebylo možné ho změnit. Teď se označuje, jak ClientSetNull
je popsáno v další části.
Databáze je také možné nakonfigurovat tak, aby při odstranění objektu zabezpečení nebo nadřazeného objektu v volitelné relaci kaskádovaly hodnoty null. To je ale mnohem méně běžné než použití kaskádových odstranění v databázi. Použití kaskádových odstranění a kaskádových hodnot null v databázi ve stejnou dobu bude téměř vždy vést k cyklům relací při použití SQL Serveru. Další informace o konfiguraci kaskádových hodnot null najdete v další části.
Konfigurace kaskádových chování
Tip
Než sem přijdete, nezapomeňte si přečíst výše uvedené části. Možnosti konfigurace pravděpodobně nebudou dávat smysl, pokud předchozí materiál není srozumitelný.
Kaskádové chování se konfiguruje pro každou relaci pomocí OnDelete metody v OnModelCreating. Příklad:
protected override void OnModelCreating(ModelBuilder modelBuilder)
{
modelBuilder
.Entity<Blog>()
.HasOne(e => e.Owner)
.WithOne(e => e.OwnedBlog)
.OnDelete(DeleteBehavior.ClientCascade);
}
Další informace o konfiguraci relací mezi typy entit najdete v tématu Relace .
OnDelete
přijímá hodnotu z, nepochybně matoucí, DeleteBehavior výčtu. Tento výčet definuje chování EF Core u sledovaných entit a konfiguraci kaskádového odstranění v databázi při použití EF k vytvoření schématu.
Dopad na schéma databáze
Následující tabulka ukazuje výsledek každé OnDelete
hodnoty omezení cizího klíče vytvořeného migrací EF Core nebo EnsureCreated.
DeleteBehavior | Dopad na schéma databáze |
---|---|
Cascade | PŘI ODSTRANĚNÍ KASKÁDY |
Omezit | ON DELETE RESTRICT |
NoAction | výchozí nastavení databáze |
SetNull | PŘI ODSTRANĚNÍ SET NULL |
ClientSetNull | výchozí nastavení databáze |
ClientCascade | výchozí nastavení databáze |
ClientNoAction | výchozí nastavení databáze |
Chování ON DELETE NO ACTION
(výchozí nastavení databáze) a ON DELETE RESTRICT
v relačních databázích jsou obvykle identické nebo velmi podobné. I přes to, co NO ACTION
může znamenat, obě tyto možnosti způsobují vynucení referenčních omezení. Rozdíl, pokud existuje, je , když databáze kontroluje omezení. Konkrétní rozdíly mezi ON DELETE NO ACTION
databázovým systémem a ON DELETE RESTRICT
databázovým systémem najdete v dokumentaci k databázi.
SQL Server nepodporuje ON DELETE RESTRICT
, takže ON DELETE NO ACTION
se používá místo toho.
Jediné hodnoty, které způsobí kaskádové chování v databázi, jsou Cascade
a SetNull
. Všechny ostatní hodnoty nakonfigurují databázi tak, aby nepřišly kaskádové změny.
Dopad na chování SaveChanges
Tabulky v následujících částech se týkají toho, co se stane se závislými/podřízenými entitami při odstranění objektu zabezpečení nebo nadřazeného objektu nebo jeho vztahu k závislým/podřízeným entitám. Každá tabulka obsahuje jednu z těchto možností:
- Volitelné (FK s možnou hodnotou null) a požadované relace (nenulovatelné FK)
- Při načtení a sledování závislých/podřízených položek dbContext a jejich existence pouze v databázi
Požadovaný vztah se načtenými závislými/podřízenými objekty
DeleteBehavior | Při odstraňování objektu zabezpečení nebo nadřazeného objektu | Při dělení z objektu zabezpečení nebo nadřazeného objektu |
---|---|---|
Cascade | Závislé položky odstraněné ef Core | Závislé položky odstraněné ef Core |
Omezit | InvalidOperationException |
InvalidOperationException |
NoAction | InvalidOperationException |
InvalidOperationException |
SetNull | SqlException při vytváření databáze |
SqlException při vytváření databáze |
ClientSetNull | InvalidOperationException |
InvalidOperationException |
ClientCascade | Závislé položky odstraněné ef Core | Závislé položky odstraněné ef Core |
ClientNoAction | DbUpdateException |
InvalidOperationException |
Poznámky:
- Výchozí hodnota požadovaných relací je
Cascade
. - Při použití jiného než kaskádového odstranění požadovaných relací dojde k výjimce při zavolání SaveChanges.
- Obvykle se jedná o ef
InvalidOperationException
Core, protože v načtených podřízených/závislých objektech se zjistí neplatný stav. ClientNoAction
Vynutí EF Core, aby před jejich odesláním do databáze nezkontrolovala závislé funkce EF Core, takže v tomto případě databáze vyvolá výjimku, která se pak zabalí doDbUpdateException
funkce SaveChanges.SetNull
při vytváření databáze se odmítne, protože sloupec cizího klíče nemá hodnotu null.
- Obvykle se jedná o ef
- Vzhledem k tomu, že jsou načítány závislé osoby nebo podřízené položky, ef Core je vždy odstraní a databáze se nikdy neodstraní.
Požadovaný vztah se závislými/podřízenými objekty se nenačetl
DeleteBehavior | Při odstraňování objektu zabezpečení nebo nadřazeného objektu | Při dělení z objektu zabezpečení nebo nadřazeného objektu |
---|---|---|
Cascade | Závislé položky odstraněné databází | – |
Omezit | DbUpdateException |
– |
NoAction | DbUpdateException |
– |
SetNull | SqlException při vytváření databáze |
– |
ClientSetNull | DbUpdateException |
– |
ClientCascade | DbUpdateException |
– |
ClientNoAction | DbUpdateException |
– |
Poznámky:
- Dělení relace zde není platné, protože závislé/podřízené položky nejsou načteny.
- Výchozí hodnota požadovaných relací je
Cascade
. - Při použití jiného než kaskádového odstranění požadovaných relací dojde k výjimce při zavolání SaveChanges.
- Obvykle je to proto
DbUpdateException
, že závislé/podřízené položky nejsou načteny, a proto může databáze zjistit neplatný stav. SaveChanges pak zabalí výjimku databáze do .DbUpdateException
SetNull
při vytváření databáze se odmítne, protože sloupec cizího klíče nemá hodnotu null.
- Obvykle je to proto
Volitelný vztah se načtenými závislými/podřízenými objekty
DeleteBehavior | Při odstraňování objektu zabezpečení nebo nadřazeného objektu | Při dělení z objektu zabezpečení nebo nadřazeného objektu |
---|---|---|
Cascade | Závislé položky odstraněné ef Core | Závislé položky odstraněné ef Core |
Omezit | Závislé sady FK nastavené na hodnotu null podle EF Core | Závislé sady FK nastavené na hodnotu null podle EF Core |
NoAction | Závislé sady FK nastavené na hodnotu null podle EF Core | Závislé sady FK nastavené na hodnotu null podle EF Core |
SetNull | Závislé sady FK nastavené na hodnotu null podle EF Core | Závislé sady FK nastavené na hodnotu null podle EF Core |
ClientSetNull | Závislé sady FK nastavené na hodnotu null podle EF Core | Závislé sady FK nastavené na hodnotu null podle EF Core |
ClientCascade | Závislé položky odstraněné ef Core | Závislé položky odstraněné ef Core |
ClientNoAction | DbUpdateException |
Závislé sady FK nastavené na hodnotu null podle EF Core |
Poznámky:
- Výchozí hodnota pro volitelné relace, jako je
ClientSetNull
tato. - Závislé osoby nebo podřízené položky se nikdy neodstraní, pokud
Cascade
nejsouClientCascade
nakonfigurované. - Všechny ostatní hodnoty způsobí, že závislé sady FK se nastaví na hodnotu null ef Core...
- ... s výjimkou
ClientNoAction
toho, že EF Core nemá při odstranění objektu zabezpečení nebo nadřazeného objektu dotýkat cizí klíče závislých/podřízených položek. Databáze proto vyvolá výjimku, která je zabalena jakoDbUpdateException
saveChanges.
- ... s výjimkou
Nepovinný vztah se závislými/podřízenými objekty, které nejsou načteny
DeleteBehavior | Při odstraňování objektu zabezpečení nebo nadřazeného objektu | Při dělení z objektu zabezpečení nebo nadřazeného objektu |
---|---|---|
Cascade | Závislé položky odstraněné databází | – |
Omezit | DbUpdateException |
– |
NoAction | DbUpdateException |
– |
SetNull | Závislé sady FK nastavené na hodnotu null podle databáze | – |
ClientSetNull | DbUpdateException |
– |
ClientCascade | DbUpdateException |
– |
ClientNoAction | DbUpdateException |
– |
Poznámky:
- Dělení relace zde není platné, protože závislé/podřízené položky nejsou načteny.
- Výchozí hodnota pro volitelné relace, jako je
ClientSetNull
tato. - Závislé osoby a podřízené položky musí být načteny, aby se zabránilo výjimce databáze, pokud nebyla databáze nakonfigurována tak, aby kaskádově odstraňovala nebo null.