Usuwanie kaskadoweCascade Delete

Usuwanie kaskadowe jest najczęściej używany w terminologii bazy danych do opisania cechę, która umożliwia usunięcie wiersza automatycznie wyzwalać usunięcie powiązane wiersze.Cascade delete is commonly used in database terminology to describe a characteristic that allows the deletion of a row to automatically trigger the deletion of related rows. Ściśle powiązanych koncepcji, również pasuje do żadnego zachowań usuwania programu EF Core jest automatyczne usuwanie obiektu podrzędnego, gdy relacji do elementu nadrzędnego zostały oddzielone — jest to często nazywane "Usuwanie porzucone".A closely related concept also covered by EF Core delete behaviors is the automatic deletion of a child entity when it's relationship to a parent has been severed--this is commonly known as "deleting orphans".

EF Core implementuje kilka różnych delete zachowań i umożliwia konfigurację zachowania Usuń poszczególne relacji.EF Core implements several different delete behaviors and allows for the configuration of the delete behaviors of individual relationships. EF Core implementuje również konwencje, które automatycznie konfigurują zachowania delete przydatne domyślne dla każdej relacji na podstawie requiredness relacji.EF Core also implements conventions that automatically configure useful default delete behaviors for each relationship based on the requiredness of the relationship.

Usuń zachowaniaDelete behaviors

Usuń zachowania są zdefiniowane w DeleteBehavior moduł wyliczający typu i mogą być przekazywane do OnDelete wygodnego interfejsu API do kontroli czy usunięcie jednostki jednostki/element nadrzędny lub severing programu Relacja do podmiotów zależnych od ustawień lokalnych/podrzędny musi mieć efekt uboczny w jednostek zależnych od ustawień lokalnych/podrzędny.Delete behaviors are defined in the DeleteBehavior enumerator type and can be passed to the OnDelete fluent API to control whether the deletion of a principal/parent entity or the severing of the relationship to dependent/child entities should have a side effect on the dependent/child entities.

Dostępne są trzy akcje, które EF można podjąć, gdy jednostka jednostki/nadrzędna została usunięta lub jest oddzielone relacji do elementu podrzędnego:There are three actions EF can take when a principal/parent entity is deleted or the relationship to the child is severed:

  • Można je usunąć podrzędnych/zależnych od ustawień lokalnychThe child/dependent can be deleted
  • Wartości klucza obcego elementu podrzędnego można ustawić na wartość nullThe child's foreign key values can be set to null
  • Element podrzędny nie jest zmienianyThe child remains unchanged

Uwaga

Zachowanie dotyczące usuwania konfigurowane w modelu platformy EF Core jest stosowane tylko jednostki głównej jest usuwana za pomocą programu EF Core i podmioty zależne są ładowane do pamięci (czyli pod kątem śledzonych zależności).The delete behavior configured in the EF Core model is only applied when the principal entity is deleted using EF Core and the dependent entities are loaded in memory (that is, for tracked dependents). Odpowiednie zachowania kaskadowe musi być Instalator w bazie danych, aby upewnić się, dane, które nie jest śledzony przez kontekst ma niezbędnych działań, które są stosowane.A corresponding cascade behavior needs to be setup in the database to ensure data that is not being tracked by the context has the necessary action applied. Jeśli użyjesz programu EF Core do utworzenia bazy danych tego zachowania kaskadowe będzie Instalatora dla Ciebie.If you use EF Core to create the database, this cascade behavior will be setup for you.

Dla drugiego z powyższej akcji ustawienie wartości klucza obcego o wartości null jest nieprawidłowa w przypadku klucza obcego nie dopuszcza wartości null.For the second action above, setting a foreign key value to null is not valid if foreign key is not nullable. (Dopuszcza klucz obcy jest odpowiednikiem wymaganej relacji). W takich przypadkach programu EF Core śledzi, czy właściwość klucza obcego została oznaczona jako wartości null do momentu SaveChanges jest wywoływana, co jest zgłaszany wyjątek, ponieważ zmiana nie może zostać utrwalona w bazie danych.(A non-nullable foreign key is equivalent to a required relationship.) In these cases, EF Core tracks that the foreign key property has been marked as null until SaveChanges is called, at which time an exception is thrown because the change cannot be persisted to the database. Jest to podobne do pobierania naruszenie ograniczenia z bazy danych.This is similar to getting a constraint violation from the database.

Istnieją cztery Usuń zachowań, zgodnie z opisem w poniższych tabelach.There are four delete behaviors, as listed in the tables below.

Opcjonalne relacjiOptional relationships

W przypadku relacji opcjonalne (dopuszcza wartości null z kluczem obcym) on jest można zapisać wartości null wartości klucza obcego, co powoduje następujące skutki:For optional relationships (nullable foreign key) it is possible to save a null foreign key value, which results in the following effects:

Nazwa zachowaniaBehavior Name Wpływ na zależnych od ustawień lokalnych/podrzędny w pamięciEffect on dependent/child in memory Wpływ na zależnych od ustawień lokalnych/podrzędnej bazy danychEffect on dependent/child in database
KaskadoweCascade Jednostki są usuwane.Entities are deleted Jednostki są usuwane.Entities are deleted
ClientSetNull (opcja domyślna)ClientSetNull (Default) Właściwości klucza obcego są ustawione na wartość nullForeign key properties are set to null BrakNone
SetNullSetNull Właściwości klucza obcego są ustawione na wartość nullForeign key properties are set to null Właściwości klucza obcego są ustawione na wartość nullForeign key properties are set to null
ograniczeniaRestrict BrakNone BrakNone

Wymagane relacjeRequired relationships

W przypadku relacji (innych niż null z kluczem obcym), wymagane jest nie można zapisać wartości null wartości klucza obcego, co powoduje następujące skutki:For required relationships (non-nullable foreign key) it is not possible to save a null foreign key value, which results in the following effects:

Nazwa zachowaniaBehavior Name Wpływ na zależnych od ustawień lokalnych/podrzędny w pamięciEffect on dependent/child in memory Wpływ na zależnych od ustawień lokalnych/podrzędnej bazy danychEffect on dependent/child in database
Kaskadowe (opcja domyślna)Cascade (Default) Jednostki są usuwane.Entities are deleted Jednostki są usuwane.Entities are deleted
ClientSetNullClientSetNull Zgłasza SaveChangesSaveChanges throws BrakNone
SetNullSetNull Zgłasza SaveChangesSaveChanges throws Zgłasza SaveChangesSaveChanges throws
ograniczeniaRestrict BrakNone BrakNone

W tabelach powyżej Brak może doprowadzić do naruszenia ograniczenia.In the tables above, None can result in a constraint violation. Na przykład jeśli jednostka jednostki/podrzędny jest usuwana, lecz nie podjęto żadnej akcji można zmienić klucza obcego z zależnych od ustawień lokalnych/podrzędny, następnie bazie danych prawdopodobnie zgłosi na SaveChanges z powodu naruszenia ograniczenia obcego.For example, if a principal/child entity is deleted but no action is taken to change the foreign key of a dependent/child, then the database will likely throw on SaveChanges due to a foreign constraint violation.

Na wysokim poziomie:At a high level:

  • Jeśli masz jednostek, które nie mogą istnieć bez klasy nadrzędnej, a EF automatyzującą automatycznego usuwania elementy podrzędne, a następnie użyć Cascade.If you have entities that cannot exist without a parent, and you want EF to take care for deleting the children automatically, then use Cascade.
    • Jednostki, które nie mogą znajdować się bez nadrzędnej zwykle należy na użytek wymaganych relacji, które Cascade jest ustawieniem domyślnym.Entities that cannot exist without a parent usually make use of required relationships, for which Cascade is the default.
  • Jeśli masz jednostek, które mogą lub nie może mieć elementu nadrzędnego i EF, aby zadbać o nulling się klucz obcy dla Ciebie, a następnie użyć ClientSetNullIf you have entities that may or may not have a parent, and you want EF to take care of nulling out the foreign key for you, then use ClientSetNull
    • Jednostek, które może istnieć bez nadrzędnej zwykle należy użyć opcjonalne relacji, dla którego ClientSetNull jest ustawieniem domyślnym.Entities that can exist without a parent usually make use of optional relationships, for which ClientSetNull is the default.
    • Jeśli mają również próbować nawet propagację wartości null do podrzędnych klucze obce w bazie danych po jednostce podrzędnej nie został załadowany, następnie za pomocą SetNull.If you want the database to also try to propagate null values to child foreign keys even when the child entity is not loaded, then use SetNull. Jednak pamiętaj, że baza danych musi obsługiwać to Konfigurowanie bazy danych, np. to może spowodować inne ograniczenia, co w praktyce często sprawia, że ta opcja niepraktyczne.However, note that the database must support this, and configuring the database like this can result in other restrictions, which in practice often makes this option impractical. Dlatego SetNull nie jest ustawieniem domyślnym.This is why SetNull is not the default.
  • Jeśli nie chcesz programu EF Core kiedykolwiek automatycznie Usuń jednostkę lub wartość null out klucza obcego, automatycznie, a następnie użyć Ogranicz.If you don't want EF Core to ever delete an entity automatically or null out the foreign key automatically, then use Restrict. Należy pamiętać, że wymaga to, że Twój kod Synchronizuj podrzędnych jednostek i ich wartości klucza obcego ręcznie w przeciwnym razie ograniczenie wyjątki zostanie wygenerowany.Note that this requires that your code keep child entities and their foreign key values in sync manually otherwise constraint exceptions will be thrown.

Uwaga

W programie EF Core, w odróżnieniu od EF6 efekty kaskadowych nie nawiązały natychmiast, ale zamiast tego tylko wtedy, gdy jest wywoływana SaveChanges.In EF Core, unlike EF6, cascading effects do not happen immediately, but instead only when SaveChanges is called.

Uwaga

Zmiany w programie EF Core 2.0: w poprzednich wersjach Ogranicz spowodowałoby opcjonalne właściwości klucza obcego w śledzonych jednostki zależne, należy ustawić wartości null i zostało domyślne zachowanie dla relacji opcjonalne przy usuwaniu.Changes in EF Core 2.0: In previous releases, Restrict would cause optional foreign key properties in tracked dependent entities to be set to null, and was the default delete behavior for optional relationships. W programie EF Core 2.0 ClientSetNull została wprowadzona do reprezentowania tego zachowania i stało się domyślnie w przypadku relacji opcjonalne.In EF Core 2.0, the ClientSetNull was introduced to represent that behavior and became the default for optional relationships. Zachowanie Ogranicz została dostosowana do nigdy nie ma żadnych efektów ubocznych na jednostki zależne.The behavior of Restrict was adjusted to never have any side effects on dependent entities.

Przykłady usuwania jednostkiEntity deletion examples

Poniższy kod jest częścią przykładowe , można pobrać i uruchomić.The code below is part of a sample that can be downloaded and run. Przykład pokazuje, co się stanie dla każdego zachowanie dotyczące usuwania dla relacji wymagane i opcjonalne, po usunięciu obiektu nadrzędnego.The sample shows what happens for each delete behavior for both optional and required relationships when a parent entity is deleted.

var blog = context.Blogs.Include(b => b.Posts).First();
var posts = blog.Posts.ToList();

DumpEntities("  After loading entities:", context, blog, posts);

context.Remove(blog);

DumpEntities($"  After deleting blog '{blog.BlogId}':", context, blog, posts);

try
{
    Console.WriteLine();
    Console.WriteLine("  Saving changes:");

    context.SaveChanges();

    DumpSql();

    DumpEntities("  After SaveChanges:", context, blog, posts);
}
catch (Exception e)
{
    DumpSql();

    Console.WriteLine();
    Console.WriteLine($"  SaveChanges threw {e.GetType().Name}: {(e is DbUpdateException ? e.InnerException.Message : e.Message)}");
}

Przejdźmy teraz przez poszczególnych odmian, aby zrozumieć, co się dzieje.Let's walk through each variation to understand what is happening.

DeleteBehavior.Cascade z relacją wymagane lub opcjonalneDeleteBehavior.Cascade with required or optional relationship

  After loading entities:
    Blog '1' is in state Unchanged with 2 posts referenced.
      Post '1' is in state Unchanged with FK '1' and reference to blog '1'.
      Post '2' is in state Unchanged with FK '1' and reference to blog '1'.

  After deleting blog '1':
    Blog '1' is in state Deleted with 2 posts referenced.
      Post '1' is in state Unchanged with FK '1' and reference to blog '1'.
      Post '2' is in state Unchanged with FK '1' and reference to blog '1'.

  Saving changes:
    DELETE FROM [Posts] WHERE [PostId] = 1
    DELETE FROM [Posts] WHERE [PostId] = 2
    DELETE FROM [Blogs] WHERE [BlogId] = 1

  After SaveChanges:
    Blog '1' is in state Detached with 2 posts referenced.
      Post '1' is in state Detached with FK '1' and no reference to a blog.
      Post '2' is in state Detached with FK '1' and no reference to a blog.
  • Blog jest oznaczony jako usuniętyBlog is marked as Deleted
  • Wpisy początkowo pozostać Unchanged, ponieważ kaskady tak się nie stanie do momentu SaveChangesPosts initially remain Unchanged since cascades do not happen until SaveChanges
  • SaveChanges wysyła usuwa zarówno zależności/podrzędnych (wpisy), a następnie jednostkę/element nadrzędny (blog)SaveChanges sends deletes for both dependents/children (posts) and then the principal/parent (blog)
  • Po zapisaniu wszystkich jednostek są odłączone od teraz zostały usunięte z bazy danychAfter saving, all entities are detached since they have now been deleted from the database

DeleteBehavior.ClientSetNull lub DeleteBehavior.SetNull z wymaganą relacjęDeleteBehavior.ClientSetNull or DeleteBehavior.SetNull with required relationship

  After loading entities:
    Blog '1' is in state Unchanged with 2 posts referenced.
      Post '1' is in state Unchanged with FK '1' and reference to blog '1'.
      Post '2' is in state Unchanged with FK '1' and reference to blog '1'.

  After deleting blog '1':
    Blog '1' is in state Deleted with 2 posts referenced.
      Post '1' is in state Unchanged with FK '1' and reference to blog '1'.
      Post '2' is in state Unchanged with FK '1' and reference to blog '1'.

  Saving changes:
    UPDATE [Posts] SET [BlogId] = NULL WHERE [PostId] = 1

  SaveChanges threw DbUpdateException: Cannot insert the value NULL into column 'BlogId', table 'EFSaving.CascadeDelete.dbo.Posts'; column does not allow nulls. UPDATE fails. The statement has been terminated.
  • Blog jest oznaczony jako usuniętyBlog is marked as Deleted
  • Wpisy początkowo pozostać Unchanged, ponieważ kaskady tak się nie stanie do momentu SaveChangesPosts initially remain Unchanged since cascades do not happen until SaveChanges
  • SaveChanges podejmuje próbę ustawienia wpisu klucza Obcego na wartość null, ale to nie powiodło się ponieważ klucza Obcego nie dopuszcza wartości nullSaveChanges attempts to set the post FK to null, but this fails because the FK is not nullable

DeleteBehavior.ClientSetNull lub DeleteBehavior.SetNull z opcjonalną relacjęDeleteBehavior.ClientSetNull or DeleteBehavior.SetNull with optional relationship

  After loading entities:
    Blog '1' is in state Unchanged with 2 posts referenced.
      Post '1' is in state Unchanged with FK '1' and reference to blog '1'.
      Post '2' is in state Unchanged with FK '1' and reference to blog '1'.

  After deleting blog '1':
    Blog '1' is in state Deleted with 2 posts referenced.
      Post '1' is in state Unchanged with FK '1' and reference to blog '1'.
      Post '2' is in state Unchanged with FK '1' and reference to blog '1'.

  Saving changes:
    UPDATE [Posts] SET [BlogId] = NULL WHERE [PostId] = 1
    UPDATE [Posts] SET [BlogId] = NULL WHERE [PostId] = 2
    DELETE FROM [Blogs] WHERE [BlogId] = 1

  After SaveChanges:
    Blog '1' is in state Detached with 2 posts referenced.
      Post '1' is in state Unchanged with FK 'null' and no reference to a blog.
      Post '2' is in state Unchanged with FK 'null' and no reference to a blog.
  • Blog jest oznaczony jako usuniętyBlog is marked as Deleted
  • Wpisy początkowo pozostać Unchanged, ponieważ kaskady tak się nie stanie do momentu SaveChangesPosts initially remain Unchanged since cascades do not happen until SaveChanges
  • Próby SaveChanges ustawia klucza Obcego z obu zależności/elementów podrzędnych (ogłoszeń) o wartości null przed usunięciem jednostki/element nadrzędny (blog)SaveChanges attempts sets the FK of both dependents/children (posts) to null before deleting the principal/parent (blog)
  • Po zapisaniu jednostki/element nadrzędny (blog) zostanie usunięty, ale zależności/elementy podrzędne (ogłoszeń) nadal są śledzone.After saving, the principal/parent (blog) is deleted, but the dependents/children (posts) are still tracked
  • Śledzone zależności/elementy podrzędne (ogłoszeń) ma wartości null klucza Obcego, a ich odwołania do jednostki/nadrzędnych usunięte (blog) została usunięta.The tracked dependents/children (posts) now have null FK values and their reference to the deleted principal/parent (blog) has been removed

DeleteBehavior.Restrict z relacją wymagane lub opcjonalneDeleteBehavior.Restrict with required or optional relationship

  After loading entities:
    Blog '1' is in state Unchanged with 2 posts referenced.
      Post '1' is in state Unchanged with FK '1' and reference to blog '1'.
      Post '2' is in state Unchanged with FK '1' and reference to blog '1'.

  After deleting blog '1':
    Blog '1' is in state Deleted with 2 posts referenced.
      Post '1' is in state Unchanged with FK '1' and reference to blog '1'.
      Post '2' is in state Unchanged with FK '1' and reference to blog '1'.

  Saving changes:
  SaveChanges threw InvalidOperationException: The association between entity types 'Blog' and 'Post' has been severed but the foreign key for this relationship cannot be set to null. If the dependent entity should be deleted, then setup the relationship to use cascade deletes.
  • Blog jest oznaczony jako usuniętyBlog is marked as Deleted
  • Wpisy początkowo pozostać Unchanged, ponieważ kaskady tak się nie stanie do momentu SaveChangesPosts initially remain Unchanged since cascades do not happen until SaveChanges
  • Ponieważ Ogranicz informuje EF, aby automatycznie ustawić klucza Obcego o wartości null, pozostaje inną niż null, i SaveChanges zgłasza bez zapisywaniaSince Restrict tells EF to not automatically set the FK to null, it remains non-null and SaveChanges throws without saving

Usuń porzucone przykładyDelete orphans examples

Poniższy kod jest częścią przykładowe , można pobrać i uruchomić.The code below is part of a sample that can be downloaded and run. Przykład pokazuje, co się stanie dla każdego zachowanie dotyczące usuwania dla relacji wymagane i opcjonalne po relacji między nadrzędnym/jednostki i jego elementy podrzędne/dependents jest oddzielone.The sample shows what happens for each delete behavior for both optional and required relationships when the relationship between a parent/principal and its children/dependents is severed. W tym przykładzie relacji jest oddzielone przez usunięcie zależności/elementy podrzędne (ogłoszeń) z właściwości nawigacji kolekcji jednostki/nadrzędnej (blog).In this example, the relationship is severed by removing the dependents/children (posts) from the collection navigation property on the principal/parent (blog). Jednak to zachowanie jest taka sama Jeśli odwołanie z zależnych od ustawień lokalnych/podrzędny do podmiotu zabezpieczeń/element nadrzędny jest zamiast tego pustych.However, the behavior is the same if the reference from dependent/child to principal/parent is instead nulled out.

var blog = context.Blogs.Include(b => b.Posts).First();
var posts = blog.Posts.ToList();

DumpEntities("  After loading entities:", context, blog, posts);

blog.Posts.Clear();

DumpEntities("  After making posts orphans:", context, blog, posts);

try
{
    Console.WriteLine();
    Console.WriteLine("  Saving changes:");

    context.SaveChanges();

    DumpSql();

    DumpEntities("  After SaveChanges:", context, blog, posts);
}
catch (Exception e)
{
    DumpSql();

    Console.WriteLine();
    Console.WriteLine($"  SaveChanges threw {e.GetType().Name}: {(e is DbUpdateException ? e.InnerException.Message : e.Message)}");
}

Przejdźmy teraz przez poszczególnych odmian, aby zrozumieć, co się dzieje.Let's walk through each variation to understand what is happening.

DeleteBehavior.Cascade z relacją wymagane lub opcjonalneDeleteBehavior.Cascade with required or optional relationship

  After loading entities:
    Blog '1' is in state Unchanged with 2 posts referenced.
      Post '1' is in state Unchanged with FK '1' and reference to blog '1'.
      Post '2' is in state Unchanged with FK '1' and reference to blog '1'.

  After making posts orphans:
    Blog '1' is in state Unchanged with 2 posts referenced.
      Post '1' is in state Modified with FK '1' and no reference to a blog.
      Post '2' is in state Modified with FK '1' and no reference to a blog.

  Saving changes:
    DELETE FROM [Posts] WHERE [PostId] = 1
    DELETE FROM [Posts] WHERE [PostId] = 2

  After SaveChanges:
    Blog '1' is in state Unchanged with 2 posts referenced.
      Post '1' is in state Detached with FK '1' and no reference to a blog.
      Post '2' is in state Detached with FK '1' and no reference to a blog.
  • Wpisy są oznaczane jako zmodyfikowane, ponieważ severing relacji klucza Obcego być oznaczony jako wartość nullPosts are marked as Modified because severing the relationship caused the FK to be marked as null
    • W przypadku klucza Obcego nie dopuszcza wartości null, następnie wartość rzeczywista nie zmieni, nawet jeśli nie jest oznaczona jako wartości nullIf the FK is not nullable, then the actual value will not change even though it is marked as null
  • SaveChanges wysyła usuwa dla zależności/dzieci (wpisów)SaveChanges sends deletes for dependents/children (posts)
  • Po zapisaniu zależności/elementy podrzędne (ogłoszeń) są odłączone od teraz zostały usunięte z bazy danychAfter saving, the dependents/children (posts) are detached since they have now been deleted from the database

DeleteBehavior.ClientSetNull lub DeleteBehavior.SetNull z wymaganą relacjęDeleteBehavior.ClientSetNull or DeleteBehavior.SetNull with required relationship

  After loading entities:
    Blog '1' is in state Unchanged with 2 posts referenced.
      Post '1' is in state Unchanged with FK '1' and reference to blog '1'.
      Post '2' is in state Unchanged with FK '1' and reference to blog '1'.

  After making posts orphans:
    Blog '1' is in state Unchanged with 2 posts referenced.
      Post '1' is in state Modified with FK 'null' and no reference to a blog.
      Post '2' is in state Modified with FK 'null' and no reference to a blog.

  Saving changes:
    UPDATE [Posts] SET [BlogId] = NULL WHERE [PostId] = 1

  SaveChanges threw DbUpdateException: Cannot insert the value NULL into column 'BlogId', table 'EFSaving.CascadeDelete.dbo.Posts'; column does not allow nulls. UPDATE fails. The statement has been terminated.
  • Wpisy są oznaczane jako zmodyfikowane, ponieważ severing relacji klucza Obcego być oznaczony jako wartość nullPosts are marked as Modified because severing the relationship caused the FK to be marked as null
    • W przypadku klucza Obcego nie dopuszcza wartości null, następnie wartość rzeczywista nie zmieni, nawet jeśli nie jest oznaczona jako wartości nullIf the FK is not nullable, then the actual value will not change even though it is marked as null
  • SaveChanges podejmuje próbę ustawienia wpisu klucza Obcego na wartość null, ale to nie powiodło się ponieważ klucza Obcego nie dopuszcza wartości nullSaveChanges attempts to set the post FK to null, but this fails because the FK is not nullable

DeleteBehavior.ClientSetNull lub DeleteBehavior.SetNull z opcjonalną relacjęDeleteBehavior.ClientSetNull or DeleteBehavior.SetNull with optional relationship

  After loading entities:
    Blog '1' is in state Unchanged with 2 posts referenced.
      Post '1' is in state Unchanged with FK '1' and reference to blog '1'.
      Post '2' is in state Unchanged with FK '1' and reference to blog '1'.

  After making posts orphans:
    Blog '1' is in state Unchanged with 2 posts referenced.
      Post '1' is in state Modified with FK 'null' and no reference to a blog.
      Post '2' is in state Modified with FK 'null' and no reference to a blog.

  Saving changes:
    UPDATE [Posts] SET [BlogId] = NULL WHERE [PostId] = 1
    UPDATE [Posts] SET [BlogId] = NULL WHERE [PostId] = 2

  After SaveChanges:
    Blog '1' is in state Unchanged with 2 posts referenced.
      Post '1' is in state Unchanged with FK 'null' and no reference to a blog.
      Post '2' is in state Unchanged with FK 'null' and no reference to a blog.
  • Wpisy są oznaczane jako zmodyfikowane, ponieważ severing relacji klucza Obcego być oznaczony jako wartość nullPosts are marked as Modified because severing the relationship caused the FK to be marked as null
    • W przypadku klucza Obcego nie dopuszcza wartości null, następnie wartość rzeczywista nie zmieni, nawet jeśli nie jest oznaczona jako wartości nullIf the FK is not nullable, then the actual value will not change even though it is marked as null
  • SaveChanges ustawia klucza Obcego z obu zależności/elementów podrzędnych (ogłoszeń) o wartości nullSaveChanges sets the FK of both dependents/children (posts) to null
  • Po zapisaniu zależności/elementy podrzędne (ogłoszeń) ma wartości null klucza Obcego, a ich odwołania do jednostki/nadrzędnych usunięte (blog) została usunięta.After saving, the dependents/children (posts) now have null FK values and their reference to the deleted principal/parent (blog) has been removed

DeleteBehavior.Restrict z relacją wymagane lub opcjonalneDeleteBehavior.Restrict with required or optional relationship

  After loading entities:
    Blog '1' is in state Unchanged with 2 posts referenced.
      Post '1' is in state Unchanged with FK '1' and reference to blog '1'.
      Post '2' is in state Unchanged with FK '1' and reference to blog '1'.

  After making posts orphans:
    Blog '1' is in state Unchanged with 2 posts referenced.
      Post '1' is in state Modified with FK '1' and no reference to a blog.
      Post '2' is in state Modified with FK '1' and no reference to a blog.

  Saving changes:
  SaveChanges threw InvalidOperationException: The association between entity types 'Blog' and 'Post' has been severed but the foreign key for this relationship cannot be set to null. If the dependent entity should be deleted, then setup the relationship to use cascade deletes.
  • Wpisy są oznaczane jako zmodyfikowane, ponieważ severing relacji klucza Obcego być oznaczony jako wartość nullPosts are marked as Modified because severing the relationship caused the FK to be marked as null
    • W przypadku klucza Obcego nie dopuszcza wartości null, następnie wartość rzeczywista nie zmieni, nawet jeśli nie jest oznaczona jako wartości nullIf the FK is not nullable, then the actual value will not change even though it is marked as null
  • Ponieważ Ogranicz informuje EF, aby automatycznie ustawić klucza Obcego o wartości null, pozostaje inną niż null, i SaveChanges zgłasza bez zapisywaniaSince Restrict tells EF to not automatically set the FK to null, it remains non-null and SaveChanges throws without saving

Kaskadowe nieśledzone jednostekCascading to untracked entities

Gdy wywołujesz SaveChanges, reguły usuwanie kaskadowe zostaną zastosowane do dowolnej jednostki, które są śledzone przez kontekst.When you call SaveChanges, the cascade delete rules will be applied to any entities that are being tracked by the context. Jest to sytuacja we wszystkich przykładach pokazano powyżej, co jest Dlaczego SQL został wygenerowany można usunąć jednostki/element nadrzędny (blog) i wszystkie zależności/elementy podrzędne (ogłoszeń):This is the situation in all the examples shown above, which is why SQL was generated to delete both the principal/parent (blog) and all the dependents/children (posts):

    DELETE FROM [Posts] WHERE [PostId] = 1
    DELETE FROM [Posts] WHERE [PostId] = 2
    DELETE FROM [Blogs] WHERE [BlogId] = 1

Jeśli tylko podmiot zabezpieczeń jest ładowany — na przykład, gdy zapytania są tworzone dla bloga bez Include(b => b.Posts) też dołączyć wpisy — następnie SaveChanges będą generowane tylko SQL, aby usunąć jednostkę/element nadrzędny:If only the principal is loaded--for example, when a query is made for a blog without an Include(b => b.Posts) to also include posts--then SaveChanges will only generate SQL to delete the principal/parent:

    DELETE FROM [Blogs] WHERE [BlogId] = 1

Zależności/elementy podrzędne (ogłoszeń) tylko zostaną usunięte, jeśli baza danych ma odpowiedni zachowania kaskadowe skonfigurowane.The dependents/children (posts) will only be deleted if the database has a corresponding cascade behavior configured. Jeśli używasz programu EF utworzyć bazę danych, zachowania kaskadowe będzie Instalatora dla Ciebie.If you use EF to create the database, this cascade behavior will be setup for you.