Usuwanie kaskadowe

Platforma Entity Framework Core (EF Core) reprezentuje relacje przy użyciu kluczy obcych. Jednostka z kluczem obcym jest jednostką podrzędną lub zależną w relacji. Wartość klucza obcego tej jednostki musi być zgodna z wartością klucza podstawowego (lub alternatywną wartością klucza) powiązanej jednostki głównej/nadrzędnej.

Jeśli jednostka główna/nadrzędna zostanie usunięta, wartości klucza obcego zależnych/podrzędnych nie będą już zgodne z kluczem podstawowym lub alternatywnym dowolnego podmiotu zabezpieczeń/elementu nadrzędnego. Jest to nieprawidłowy stan i spowoduje naruszenie ograniczeń odwołań w większości baz danych.

Istnieją dwie opcje uniknięcia tego naruszenia ograniczeń odwołań:

  1. Ustawianie wartości FK na wartość null
  2. Usuń również jednostki zależne/podrzędne

Pierwsza opcja jest prawidłowa tylko w przypadku relacji opcjonalnych, w których właściwość klucza obcego (i kolumna bazy danych, do której jest mapowana) musi mieć wartość null.

Druga opcja jest prawidłowa dla dowolnego rodzaju relacji i jest nazywana "usuwaniem kaskadowym".

Napiwek

W tym dokumencie opisano usuwanie kaskadowe (i usuwanie osieroconych) z perspektywy aktualizowania bazy danych. To sprawia, że duże wykorzystanie pojęć wprowadzonych w usłudze Change Tracking w programie EF Core i zmiana kluczy obcych i nawigacji. Pamiętaj, aby w pełni zrozumieć te pojęcia przed rozwiązaniem problemu z materiałem tutaj.

Napiwek

Możesz uruchomić i debugować cały kod podany w tym dokumencie, pobierając przykładowy kod z serwisu GitHub.

W przypadku wystąpienia kaskadowych zachowań

Usuwanie kaskadowe jest wymagane, gdy jednostka zależna/podrzędna nie może być już skojarzona z bieżącym podmiotem zabezpieczeń/elementem nadrzędnym. Może się tak zdarzyć, ponieważ podmiot zabezpieczeń/nadrzędny jest usuwany lub może się zdarzyć, gdy podmiot zabezpieczeń/nadrzędny nadal istnieje, ale element zależny/podrzędny nie jest już z nim skojarzony.

Usuwanie podmiotu zabezpieczeń/elementu nadrzędnego

Rozważmy ten prosty model, w którym Blog jest podmiot zabezpieczeń/nadrzędny w relacji z elementem Post, który jest zależny/podrzędny. Post.BlogId to właściwość klucza obcego, której wartość musi być zgodna z kluczem Blog.Id podstawowym w blogu, do którego należy wpis.

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

Zgodnie z konwencją ta relacja jest skonfigurowana jako wymagana, ponieważ Post.BlogId właściwość klucza obcego jest niepusta. Wymagane relacje są domyślnie skonfigurowane do używania usuwania kaskadowego. Zobacz Relacje , aby uzyskać więcej informacji na temat modelowania relacji.

Podczas usuwania bloga wszystkie wpisy są usuwane kaskadowo. Na przykład:

using var context = new BlogsContext();

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

context.Remove(blog);

context.SaveChanges();

Funkcja SaveChanges generuje następujący kod SQL, używając programu SQL Server jako przykładu:

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

Zerwanie relacji

Zamiast usuwać blog, możemy zamiast tego zerwać relację między każdym wpisem a blogem. Można to zrobić, ustawiając nawigację Post.Blog referencyjną na wartość null dla każdego wpisu:

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

Relację można również zerwać, usuwając każdy wpis z Blog.Posts nawigacji kolekcji:

using var context = new BlogsContext();

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

blog.Posts.Clear();

context.SaveChanges();

W obu przypadkach wynik jest taki sam: blog nie zostanie usunięty, ale wpisy, które nie są już skojarzone z żadnym blogiem, zostaną usunięte:

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

Usuwanie jednostek, które nie są już skojarzone z żadnym podmiotem zabezpieczeń/zależności, jest nazywane "usuwaniem osieroconych".

Napiwek

Usuwanie kaskadowe i usuwanie osieroconych jest ściśle powiązane. Oba te elementy powodują usunięcie jednostek zależnych/podrzędnych, gdy relacja z wymaganym podmiotem zabezpieczeń/elementem nadrzędnym jest zerwana. W przypadku usunięcia kaskadowego następuje to zerwanie, ponieważ jednostka/element nadrzędny jest usuwany. W przypadku oddzielonych jednostka główna/nadrzędna nadal istnieje, ale nie jest już powiązana z jednostkami zależnymi/podrzędnymi.

Gdzie występują zachowania kaskadowe

Zachowania kaskadowe można zastosować do:

  • Jednostki śledzone przez bieżącą DbContext
  • Jednostki w bazie danych, które nie zostały załadowane do kontekstu

Kaskadowe usuwanie śledzonych jednostek

Program EF Core zawsze stosuje skonfigurowane zachowania kaskadowe do śledzonych jednostek. Oznacza to, że jeśli aplikacja ładuje wszystkie odpowiednie jednostki zależne/podrzędne do obiektu DbContext, jak pokazano w powyższych przykładach, zachowania kaskadowe będą prawidłowo stosowane niezależnie od konfiguracji bazy danych.

Napiwek

Dokładny czas śledzenia zachowań kaskadowych może być kontrolowany przy użyciu elementów ChangeTracker.CascadeDeleteTiming i ChangeTracker.DeleteOrphansTiming. Aby uzyskać więcej informacji, zobacz Zmienianie kluczy obcych i nawigacji.

Usuwanie kaskadowe w bazie danych

Wiele systemów baz danych oferuje również kaskadowe zachowania wyzwalane po usunięciu jednostki w bazie danych. Program EF Core konfiguruje te zachowania na podstawie zachowania usuwania kaskadowego w modelu EF Core podczas tworzenia bazy danych przy użyciu EnsureCreated migracji platformy EF Core lub EF Core. Na przykład przy użyciu powyższego modelu poniższa tabela jest tworzona dla wpisów podczas korzystania z programu 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
);

Zwróć uwagę, że ograniczenie klucza obcego definiujące relację między blogami i wpisami jest skonfigurowane za pomocą polecenia ON DELETE CASCADE.

Jeśli wiemy, że baza danych jest tak skonfigurowana, możemy usunąć blog bez uprzedniego ładowania wpisów, a baza danych zajmie się usunięciem wszystkich wpisów związanych z tym blogiem. Na przykład:

using var context = new BlogsContext();

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

context.Remove(blog);

context.SaveChanges();

Zwróć uwagę, że nie Include ma żadnych wpisów, więc nie są ładowane. Funkcja SaveChanges w tym przypadku usunie tylko blog, ponieważ jest to jedyna śledzona jednostka:

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

Spowoduje to wyjątek, jeśli ograniczenie klucza obcego w bazie danych nie jest skonfigurowane do usuwania kaskadowego. Jednak w tym przypadku wpisy są usuwane przez bazę danych, ponieważ została skonfigurowana ON DELETE CASCADE podczas jej tworzenia.

Uwaga

Bazy danych zwykle nie mają żadnego sposobu automatycznego usuwania osieroconych. Dzieje się tak dlatego, że program EF Core reprezentuje relacje korzystające z nawigacji, a także kluczy obcych, bazy danych mają tylko klucze obce i brak nawigacji. Oznacza to, że zwykle nie można zerwać relacji bez ładowania obu stron do elementu DbContext.

Uwaga

Baza danych ef Core w pamięci nie obsługuje obecnie usuwania kaskadowego w bazie danych.

Ostrzeżenie

Nie należy konfigurować usuwania kaskadowego w bazie danych podczas usuwania nietrwałego jednostek. Może to spowodować przypadkowe usunięcie jednostek zamiast usunięcia nietrwałego.

Ograniczenia kaskadowe bazy danych

Niektóre bazy danych, w szczególności program SQL Server, mają ograniczenia dotyczące zachowań kaskadowych, które tworzą cykle. Rozważmy na przykład następujący 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; }
}

Ten model ma trzy relacje, wszystkie wymagane i dlatego skonfigurowane do kaskadowego usuwania według konwencji:

  • Usunięcie bloga spowoduje kaskadowe usunięcie wszystkich powiązanych wpisów
  • Usunięcie autora wpisów spowoduje, że autoryzowane wpisy zostaną usunięte kaskadowo
  • Usunięcie właściciela bloga spowoduje, że blog zostanie usunięty kaskadowo

To wszystko jest uzasadnione (jeśli nieco drakoński w zasadach zarządzania blogami!), ale próba utworzenia bazy danych programu SQL Server z tymi kaskadowymi konfiguracjami powoduje następujący wyjątek:

Microsoft.Data.SqlClient.SqlException (0x80131904): Wprowadzenie ograniczenia KLUCZA OBCEgo "FK_Posts_Person_AuthorId" w tabeli "Posty" może powodować cykle lub wiele ścieżek kaskadowych. Określ WARTOŚĆ ON DELETE NO ACTION (USUŃ BRAK AKCJI) LUB W PRZYPADKU AKTUALIZACJI NIE AKCJI LUB Zmodyfikuj inne ograniczenia KLUCZA OBCEGO.

Istnieją dwa sposoby obsługi tej sytuacji:

  1. Zmień co najmniej jedną relację, aby nie usuwać kaskadowo.
  2. Skonfiguruj bazę danych bez co najmniej jednego z tych operacji usuwania kaskadowego, a następnie upewnij się, że wszystkie jednostki zależne są ładowane, aby program EF Core mógł wykonywać kaskadowe zachowanie.

Biorąc pod uwagę pierwsze podejście z naszym przykładem, możemy sprawić, że relacja post-blog będzie opcjonalna, dając jej właściwość klucza obcego dopuszczających wartość null:

public int? BlogId { get; set; }

Opcjonalna relacja umożliwia istnienie wpisu bez bloga, co oznacza, że usuwanie kaskadowe nie zostanie już skonfigurowane domyślnie. Oznacza to, że nie istnieje już cykl w akcjach kaskadowych, a baza danych może zostać utworzona bez błędu w programie SQL Server.

Zamiast tego, korzystając z drugiego podejścia, możemy zachować wymaganą relację właściciela blogu i skonfigurować ją do usunięcia kaskadowego, ale aby ta konfiguracja miała zastosowanie tylko do śledzonych jednostek, a nie bazy danych:

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

Teraz co się stanie, jeśli załadujemy zarówno osobę, jak i blog, który jest właścicielem, a następnie usuniemy osobę?

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

Program EF Core kaskadowo usunie właściciela, aby blog również został usunięty:

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

Jeśli jednak blog nie zostanie załadowany po usunięciu właściciela:

using var context = new BlogsContext();

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

context.Remove(owner);

context.SaveChanges();

Następnie zostanie zgłoszony wyjątek z powodu naruszenia ograniczenia klucza obcego w bazie danych:

Microsoft.Data.SqlClient.SqlException: instrukcja DELETE powoduje konflikt z ograniczeniem REFERENCE "FK_Blogs_Osoby_OwnerId". Konflikt wystąpił w bazie danych "Scratch", tabeli "dbo". Blogi", kolumna "OwnerId". Instrukcja została zakończona.

Kaskadowe wartości null

Relacje opcjonalne mają właściwości klucza obcego dopuszczane do wartości null zamapowane na kolumny bazy danych dopuszczane do wartości null. Oznacza to, że wartość klucza obcego może być ustawiona na wartość null po usunięciu bieżącego podmiotu zabezpieczeń/elementu nadrzędnego lub zerwaniu z elementu zależnego/podrzędnego.

Przyjrzyjmy się ponownie przykładom z sekcji Kiedy występują kaskadowe zachowania, ale tym razem z opcjonalną relacją reprezentowaną przez właściwość klucza obcego dopuszczającego Post.BlogId wartość null:

public int? BlogId { get; set; }

Ta właściwość klucza obcego zostanie ustawiona na wartość null dla każdego wpisu po usunięciu powiązanego bloga. Na przykład ten kod, który jest taki sam jak poprzednio:

using var context = new BlogsContext();

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

context.Remove(blog);

context.SaveChanges();

Spowoduje to teraz następujące aktualizacje bazy danych po wywołaniu funkcji 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;

Podobnie, jeśli relacja została zerwana przy użyciu jednego z powyższych przykładów:

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

Lub:

using var context = new BlogsContext();

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

blog.Posts.Clear();

context.SaveChanges();

Następnie wpisy są aktualizowane przy użyciu wartości klucza obcego o wartości null, gdy jest wywoływana funkcja 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;

Aby uzyskać więcej informacji na temat zarządzania kluczami obcymi i nawigacjami w miarę zmiany ich wartości, zobacz Zmienianie kluczy obcych i nawigacji w programie EF Core.

Uwaga

Poprawki relacji w ten sposób były domyślnym zachowaniem programu Entity Framework od pierwszej wersji w 2008 roku. Przed programem EF Core nie miała nazwy i nie można było jej zmienić. Jest on teraz znany jako ClientSetNull opisany w następnej sekcji.

Bazy danych można również skonfigurować do kaskadowych wartości null, takich jak w przypadku usunięcia podmiotu zabezpieczeń/elementu nadrzędnego w relacji opcjonalnej. Jednak jest to znacznie mniej powszechne niż używanie kaskadowych usuwania w bazie danych. Użycie kaskadowego usuwania i kaskadowego wartości null w bazie danych w tym samym czasie będzie niemal zawsze powodować cykle relacji podczas korzystania z programu SQL Server. Aby uzyskać więcej informacji na temat konfigurowania kaskadowych wartości null, zobacz następną sekcję.

Konfigurowanie zachowań kaskadowych

Napiwek

Pamiętaj, aby przeczytać powyższe sekcje przed przyjazdem tutaj. Opcje konfiguracji prawdopodobnie nie będą miały sensu, jeśli poprzedni materiał nie zostanie zrozumiany.

Zachowania kaskadowe są konfigurowane na relację OnDelete przy użyciu metody w pliku OnModelCreating. Na przykład:

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

Zobacz Relacje , aby uzyskać więcej informacji na temat konfigurowania relacji między typami jednostek.

OnDelete akceptuje wartość z wyliczenia, co prawda mylące, DeleteBehavior wyliczenie. Wyliczenie definiuje zarówno zachowanie platformy EF Core na śledzonych jednostkach, jak i konfigurację usuwania kaskadowego w bazie danych, gdy program EF jest używany do tworzenia schematu.

Wpływ na schemat bazy danych

W poniższej tabeli przedstawiono wynik każdej OnDelete wartości ograniczenia klucza obcego utworzonego przez migracje programu EF Core lub EnsureCreated.

UsuńBehavior Wpływ na schemat bazy danych
Cascade PO USUNIĘCIU KASKADY
Ogranicz PO USUNIĘCIU OGRANICZ
NoAction domyślna baza danych
Setnull PO USUNIĘCIU USTAW WARTOŚĆ NULL
ClientSetNull domyślna baza danych
ClientCascade domyślna baza danych
ClientNoAction domyślna baza danych

Zachowania ON DELETE NO ACTION (ustawienie domyślne bazy danych) i ON DELETE RESTRICT w relacyjnych bazach danych są zazwyczaj identyczne lub bardzo podobne. Pomimo tego, co NO ACTION może oznaczać, obie te opcje powodują wymuszanie ograniczeń odwołań. Różnica, gdy istnieje, polega na tym, że baza danych sprawdza ograniczenia. Zapoznaj się z dokumentacją bazy danych, aby zapoznać się z konkretnymi różnicami między ON DELETE NO ACTION i ON DELETE RESTRICT w systemie bazy danych.

Program SQL Server nie obsługuje ON DELETE RESTRICTprogramu , dlatego ON DELETE NO ACTION zamiast tego jest używany.

Jedynymi wartościami, które spowodują kaskadowe zachowania bazy danych, są Cascade i SetNull. Wszystkie inne wartości spowodują skonfigurowanie bazy danych tak, aby nie zmieniała się kaskadowo.

Wpływ na zachowanie funkcji SaveChanges

Tabele w poniższych sekcjach opisują, co się dzieje z jednostkami zależnym/podrzędnym po usunięciu podmiotu zabezpieczeń/elementu nadrzędnego lub zerwanie relacji z jednostkami zależnym/podrzędnym. Każda tabela obejmuje jedną z:

  • Opcjonalne (FK dopuszczane do wartości null) i wymagane relacje (bez wartości null)
  • Gdy zależności/elementy podrzędne są ładowane i śledzone przez element DbContext oraz gdy istnieją tylko w bazie danych

Wymagana relacja z załadowanymi zależnościami/dziećmi

UsuńBehavior Usuwanie podmiotu zabezpieczeń/elementu nadrzędnego Na odcięcie od podmiotu zabezpieczeń/elementu nadrzędnego
Cascade Zależności usunięte przez program EF Core Zależności usunięte przez program EF Core
Ogranicz InvalidOperationException InvalidOperationException
NoAction InvalidOperationException InvalidOperationException
Setnull SqlException tworzenie bazy danych SqlException tworzenie bazy danych
ClientSetNull InvalidOperationException InvalidOperationException
ClientCascade Zależności usunięte przez program EF Core Zależności usunięte przez program EF Core
ClientNoAction DbUpdateException InvalidOperationException

Uwagi:

  • Wartością domyślną dla wymaganych relacji jest następująca: Cascade.
  • Użycie niczego innego niż usuwanie kaskadowe dla wymaganych relacji spowoduje wyjątek, gdy jest wywoływana funkcja SaveChanges.
    • Zazwyczaj jest to element InvalidOperationException z programu EF Core, ponieważ w załadowanych elementach podrzędnych/zależnych wykryto nieprawidłowy stan.
    • ClientNoAction Wymusza, aby program EF Core nie sprawdzał zależności naprawy przed wysłaniem ich do bazy danych, dlatego w tym przypadku baza danych zgłasza wyjątek, który jest następnie owinięty przez DbUpdateException polecenie SaveChanges.
    • SetNull jest odrzucany podczas tworzenia bazy danych, ponieważ kolumna klucza obcego nie może zawierać wartości null.
  • Ponieważ są ładowane zależności/elementy podrzędne, są one zawsze usuwane przez program EF Core i nigdy nie pozostawione do usunięcia bazy danych.

Wymagana relacja z nie załadowanymi zależnościami/elementy podrzędne

UsuńBehavior Usuwanie podmiotu zabezpieczeń/elementu nadrzędnego Na odcięcie od podmiotu zabezpieczeń/elementu nadrzędnego
Cascade Zależności usunięte przez bazę danych Nie dotyczy
Ogranicz DbUpdateException Nie dotyczy
NoAction DbUpdateException Nie dotyczy
Setnull SqlException tworzenie bazy danych Nie dotyczy
ClientSetNull DbUpdateException Nie dotyczy
ClientCascade DbUpdateException Nie dotyczy
ClientNoAction DbUpdateException Nie dotyczy

Uwagi:

  • Zerwanie relacji nie jest tutaj prawidłowe, ponieważ zależności/elementy podrzędne nie są ładowane.
  • Wartością domyślną dla wymaganych relacji jest następująca: Cascade.
  • Użycie niczego innego niż usuwanie kaskadowe dla wymaganych relacji spowoduje wyjątek, gdy jest wywoływana funkcja SaveChanges.
    • Zazwyczaj jest DbUpdateException to spowodowane tym, że zależności/elementy podrzędne nie są ładowane, dlatego nieprawidłowy stan można wykryć tylko przez bazę danych. Funkcja SaveChanges następnie opakowuje wyjątek bazy danych w elemencie DbUpdateException.
    • SetNull jest odrzucany podczas tworzenia bazy danych, ponieważ kolumna klucza obcego nie może zawierać wartości null.

Opcjonalna relacja z załadowanymi zależnościami/dziećmi

UsuńBehavior Usuwanie podmiotu zabezpieczeń/elementu nadrzędnego Na odcięcie od podmiotu zabezpieczeń/elementu nadrzędnego
Cascade Zależności usunięte przez program EF Core Zależności usunięte przez program EF Core
Ogranicz Zależne zestawy FKs ustawione na wartość null przez program EF Core Zależne zestawy FKs ustawione na wartość null przez program EF Core
NoAction Zależne zestawy FKs ustawione na wartość null przez program EF Core Zależne zestawy FKs ustawione na wartość null przez program EF Core
Setnull Zależne zestawy FKs ustawione na wartość null przez program EF Core Zależne zestawy FKs ustawione na wartość null przez program EF Core
ClientSetNull Zależne zestawy FKs ustawione na wartość null przez program EF Core Zależne zestawy FKs ustawione na wartość null przez program EF Core
ClientCascade Zależności usunięte przez program EF Core Zależności usunięte przez program EF Core
ClientNoAction DbUpdateException Zależne zestawy FKs ustawione na wartość null przez program EF Core

Uwagi:

  • Wartość domyślna dla relacji opcjonalnych, takich jak ta, to ClientSetNull.
  • Zależności/elementy podrzędne nigdy nie są usuwane, chyba że Cascade są skonfigurowane.ClientCascade
  • Wszystkie inne wartości powodują ustawienie zależnych zestawów FKs na wartość null przez program EF Core...
    • ... z wyjątkiem ClientNoAction tego, co informuje ef Core, aby nie dotykał kluczy obcych zależnych/podrzędnych, gdy podmiot zabezpieczeń/nadrzędny jest usuwany. W związku z tym baza danych zgłasza wyjątek, który jest opakowany jako DbUpdateException element SaveChanges.

Opcjonalna relacja z nie załadowanymi zależnościami/elementy podrzędne

UsuńBehavior Usuwanie podmiotu zabezpieczeń/elementu nadrzędnego Na odcięcie od podmiotu zabezpieczeń/elementu nadrzędnego
Cascade Zależności usunięte przez bazę danych Nie dotyczy
Ogranicz DbUpdateException Nie dotyczy
NoAction DbUpdateException Nie dotyczy
Setnull Zależne zestawy FKs ustawione na wartość null przez bazę danych Nie dotyczy
ClientSetNull DbUpdateException Nie dotyczy
ClientCascade DbUpdateException Nie dotyczy
ClientNoAction DbUpdateException Nie dotyczy

Uwagi:

  • Zerwanie relacji nie jest tutaj prawidłowe, ponieważ zależności/elementy podrzędne nie są ładowane.
  • Wartość domyślna dla relacji opcjonalnych, takich jak ta, to ClientSetNull.
  • Zależności/elementy podrzędne należy załadować, aby uniknąć wyjątku bazy danych, chyba że baza danych została skonfigurowana do kaskadowego usunięcia lub wartości null.