Kaskadierte LöschungCascade Delete

Kaskadierte Löschung wird häufig in der Terminologie von Datenbanken verwendet, um ein Merkmal beschreiben, die das Löschen einer Zeile automatisch verknüpfte Zeilen gelöscht auslösen können.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. Ein eng verwandtes Konzept gehörig von EF Core Delete Verhalten ist das automatische Löschen von einer untergeordneten Entität wird die Beziehung zu einem übergeordneten Element unterbrochen wurde – dies geht im Allgemeinen als "verwaiste löschen" bezeichnet.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 i commonly known as "deleting orphans".

EF Core implementiert mehrere unterschiedliche Delete Verhaltensweisen und ermöglicht die Konfiguration der Delete-Verhalten von einzelnen Beziehungen.EF Core implements several different delete behaviors and allows for the configuration of the delete behaviors of individual relationships. EF Core implementiert auch Konventionen, die hilfreich, löschen Sie das Standardverhalten für jede Beziehung auf Basis der [Requiredness der Beziehung] automatisch zu konfigurieren (.. /Modeling/Relationships.MD#Required-and-optional-Relationships).EF Core also implements conventions that automatically configure useful default delete behaviors for each relationship based on the requiredness of the relationship.

Löschen von VerhaltenDelete behaviors

Löschen Verhalten wird definiert, der deleteBehavior() Enumerator geben, und übergeben werden kann, um die OnDelete fluent-API, um zu steuern, ob das Löschen einer Entität Prinzipal/im übergeordneten Element oder das Trennen von der Beziehung zu abhängige/untergeordneter Entitäten sollten einen Nebeneffekt auf abhängige/untergeordnete Entitäten enthalten.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.

Es gibt drei Aktionstypen, die EF ergreifen kann, wenn eine Entität Prinzipal/im übergeordneten Element gelöscht wird oder die Beziehung zum untergeordneten Element unterbrochen wird:There are three actions EF can take when a principal/parent entity is deleted or the relationship to the child is severed:

  • Die untergeordneten/abhängigen können gelöscht werdenThe child/dependent can be deleted
  • Fremdschlüsselwerte des untergeordneten Standorts können festgelegt werden, auf NullThe child's foreign key values can be set to null
  • Das untergeordnete Element unverändert.The child remains unchanged

Hinweis

Das Löschverhalten konfiguriert in der EF-Core-Modell wird nur angewendet, wenn prinzipalentität wird mithilfe von EF Core gelöscht, und der abhängigen Entitäten (d. h. für überwachte Nachfolger) im Arbeitsspeicher geladen werden.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 (i.e. for tracked dependents). Eine entsprechende überlappungsverhalten muss sein, dass Setup in der Datenbank, um sicherzustellen, dass Daten, die nicht vom Kontext nachverfolgt wird die erforderliche Aktion angewendet wurde.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. Wenn Sie EF Core verwenden, um die Datenbank zu erstellen, wird dieses Verhalten Cascade für Sie eingerichtet werden.If you use EF Core to create the database, this cascade behavior will be setup for you.

Für die zweite Aktion ist einen foreign Key-Wert auf null festlegen ungültig, wenn Fremdschlüssel nicht zulässig ist.For the second action above, setting a foreign key value to null is not valid if foreign key is not nullable. (Ein NULL-Fremdschlüssel entspricht eine erforderliche Beziehung). In diesen Fällen verfolgt EF Core an, dass die Fremdschlüsseleigenschaft bis SaveChanges aufgerufen wird zu diesem Zeitpunkt eine Ausnahme ausgelöst wird, da die Änderung in der Datenbank dauerhaft gespeichert werden kann, als null markiert wurde.(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. Dies ist vergleichbar mit dem eine einschränkungsverletzung aus der Datenbank abrufen.This is similar to getting a constraint violation from the database.

Es gibt vier Verhaltensweisen, löschen, wie in den folgenden Tabellen aufgeführt.There are four delete behaviors, as listed in the tables below. Für optionale Beziehungen (nullable Fremdschlüssel) es ist möglich, einen null Fremdschlüsselwert speichern vortäuschen folgenden Auswirkungen:For optional relationships (nullable foreign key) it is possible to save a null foreign key value, which results in the following effects:

VerhaltensnameBehavior Name Auswirkungen auf abhängige und untergeordneten Elementen im ArbeitsspeicherEffect on dependent/child in memory Auswirkungen auf abhängige/untergeordnete DatenbankEffect on dependent/child in database
CASCADECascade Entitäten werden gelöscht.Entities are deleted Entitäten werden gelöscht.Entities are deleted
ClientSetNull (Standard)ClientSetNull (Default) Fremdschlüsseleigenschaften festgelegt werden auf NullForeign key properties are set to null KeineNone
SetNullSetNull Fremdschlüsseleigenschaften festgelegt werden auf NullForeign key properties are set to null Fremdschlüsseleigenschaften festgelegt werden auf NullForeign key properties are set to null
EinschränkenRestrict KeineNone KeineNone

Für die erforderlichen Beziehungen (null-Fremdschlüssel) ist es nicht möglich, einen null Fremdschlüsselwert speichern vortäuschen folgenden Auswirkungen:For required relationships (non-nullable foreign key) it is not possible to save a null foreign key value, which results in the following effects:

VerhaltensnameBehavior Name Auswirkungen auf abhängige und untergeordneten Elementen im ArbeitsspeicherEffect on dependent/child in memory Auswirkungen auf abhängige/untergeordnete DatenbankEffect on dependent/child in database
CASCADE (Standard)Cascade (Default) Entitäten werden gelöscht.Entities are deleted Entitäten werden gelöscht.Entities are deleted
ClientSetNullClientSetNull SaveChanges löst ausSaveChanges throws KeineNone
SetNullSetNull SaveChanges löst ausSaveChanges throws SaveChanges löst ausSaveChanges throws
EinschränkenRestrict KeineNone KeineNone

In den obigen Tabellen keine kann zu einer Verletzung einer Einschränkung führen.In the tables above, None can result in a constraint violation. Z. B. wenn eine Prinzipal/untergeordnete Entität wird gelöscht, jedoch keine Aktion ausgeführt wird, um den Fremdschlüssel einer abhängigen/untergeordneten zu ändern, löst klicken Sie dann die Datenbank wahrscheinlich auf SaveChanges aufgrund einer einschränkungsverletzung foreign.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.

Auf hoher Ebene:At a high level:

  • Wenn Sie Entitäten, die ohne ein übergeordnetes Element vorhanden sein können, und Sie EF, achten Sie darauf für die untergeordneten Elemente automatisch gelöscht werden soll, verwenden Sie 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.
    • Entitäten, die vorhanden sein können, ohne ein übergeordnetes Element in der Regel stellen für die erforderlichen Beziehungen nutzen Cascade ist die Standardeinstellung.Entities that cannot exist without a parent usually make use of required relationships, for which Cascade is the default.
  • Wenn Sie die Entitäten, die möglicherweise verfügen möglicherweise nicht über ein übergeordnetes Element haben, und Sie EF zu kümmern, des Fremdschlüssels für Sie erheblich werden soll, verwenden Sie 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
    • Entitäten, die vorhanden sein können, ohne ein übergeordnetes Element in der Regel stellen Verwenden von optionalen Beziehungen für die ClientSetNull ist die Standardeinstellung.Entities that can exist without a parent usually make use of optional relationships, for which ClientSetNull is the default.
    • Wenn Sie die Datenbank auch versuchen, die null-Werte zu Fremdschlüsseln untergeordneten auch weitergeben soll bei die untergeordneten Entität nicht geladen wird, verwenden Sie dann 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. Beachten Sie jedoch, dass die Datenbank muss dies unterstützen, und Konfigurieren der Datenbank wie folgt dazu, andere Einschränkungen führen kann, die in der Praxis eignet sich oft diese Option nicht.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. Deswegen SetNull ist nicht der Standard.This is why SetNull is not the default.
  • Wenn Sie nicht möchten, dass EF Core jemals Löschen einer Entität automatisch oder automatisch, die den Fremdschlüssel null, dann verwenden beschränken.If you don't want EF Core to ever delete an entity automatically or null out the foreign key automatically, then use Restrict. Beachten Sie, dass dies erfordert, dass Ihr Code untergeordneten Entitäten und deren Fremdschlüsselwerte manuell synchronisieren werden andernfalls Einschränkung Ausnahmen ausgelöst werden.Note that this requires that your code keep child entities and their foreign key values in sync manually otherwise constraint exceptions will be thrown.

Hinweis

In EF Kern ausgeführt, im Gegensatz zu EF6 führen Sie kaskadierende Effekte nicht sofort, sondern stattdessen erfolgen nur, wenn SaveChanges aufgerufen wird.In EF Core, unlike EF6, cascading effects do not happen immediately, but instead only when SaveChanges is called.

Hinweis

Änderungen in EF Core 2.0: In früheren Versionen beschränken würde optionale Fremdschlüsseleigenschaften in überwachten abhängigen Entitäten festgelegt werden, null und wurde die Standardeinstellung Verhalten für optionale Beziehungen zu löschen.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. In EF Core 2.0 die ClientSetNull wurde eingeführt, um dieses Verhalten darstellen, und stattdessen der Standardwert für optionale Beziehungen.In EF Core 2.0, the ClientSetNull was introduced to represent that behavior and became the default for optional relationships. Das Verhalten des beschränken wurde angepasst, um keine Nebeneffekte nie auf abhängige Entitäten haben.The behavior of Restrict was adjusted to never have any side effects on dependent entities.

Beispiele für das Löschen von EntitätenEntity deletion examples

Der folgende Code ist Teil einer Beispiel , kann eine Ausführung heruntergeladen werden.The code below is part of a sample that can be downloaded an run. Im Beispiel wird gezeigt, was geschieht für jede Löschverhalten für optionale und notwendige Beziehungen, wenn eine übergeordnete Entität gelöscht wird.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)}");
}

Wir führen Sie durch jede Variante zu verstehen, was geschieht.Let's walk through each variation to understand what is happening.

DeleteBehavior.Cascade mit erforderlichen oder optionalen BeziehungDeleteBehavior.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 '1' 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 '1' 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 '1' is in state Detached with FK '1' and no reference to a blog.
  • Blog wird als gelöscht markiert.Blog is marked as Deleted
  • Beiträge bleiben anfänglich unverändert, da sich bis SaveChanges nicht überlappend ausgeführt werdenPosts initially remain Unchanged since cascades do not happen until SaveChanges
  • SaveChanges sendet löschungen für sowohl Dependents/untergeordnete Elemente (Beiträge), und klicken Sie dann den Prinzipal/im übergeordneten Element (Blog)SaveChanges sends deletes for both dependents/children (posts) and then the principal/parent (blog)
  • Nach dem Speichern, werden alle Entitäten getrennt, da sie jetzt aus der Datenbank gelöscht wurdenAfter saving, all entities are detached since they have now been deleted from the database

DeleteBehavior.ClientSetNull oder DeleteBehavior.SetNull mit erforderliche BeziehungDeleteBehavior.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 '1' 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 '1' 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 wird als gelöscht markiert.Blog is marked as Deleted
  • Beiträge bleiben anfänglich unverändert, da sich bis SaveChanges nicht überlappend ausgeführt werdenPosts initially remain Unchanged since cascades do not happen until SaveChanges
  • SaveChanges versucht Post-FK auf null festgelegt, aber dies schlägt fehl, da die '-fk ' nicht auf NULL festlegbar ist.SaveChanges attempts to set the post FK to null, but this fails because the FK is not nullable

DeleteBehavior.ClientSetNull oder DeleteBehavior.SetNull mit optionale BeziehungDeleteBehavior.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 '1' 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 '1' 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 '1' is in state Unchanged with FK 'null' and no reference to a blog.
  • Blog wird als gelöscht markiert.Blog is marked as Deleted
  • Beiträge bleiben anfänglich unverändert, da sich bis SaveChanges nicht überlappend ausgeführt werdenPosts initially remain Unchanged since cascades do not happen until SaveChanges
  • SaveChanges Versuche Legt die FK der abhängigen Elemente/untergeordnete Elemente (Beiträge) auf null fest, vor dem Löschen der Prinzipal/im übergeordneten Element (Blog)SaveChanges attempts sets the FK of both dependents/children (posts) to null before deleting the principal/parent (blog)
  • Nach dem Speichern der Prinzipal/im übergeordneten Element (Blog) gelöscht, jedoch werden weiterhin die abhängigen Elemente/untergeordneten Elemente (Beiträge) nachverfolgt.After saving, the principal/parent (blog) is deleted, but the dependents/children (posts) are still tracked
  • Die nachverfolgte Dependents/untergeordneten Elemente (Beiträge) haben jetzt FK Nullwerte und ihre Verweis auf die gelöschte Prinzipal/im übergeordneten Element (Blog) wurde entferntThe tracked dependents/children (posts) now have null FK values and their reference to the deleted principal/parent (blog) has been removed

DeleteBehavior.Restrict mit erforderlichen oder optionalen BeziehungDeleteBehavior.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 '1' 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 '1' 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 wird als gelöscht markiert.Blog is marked as Deleted
  • Beiträge bleiben anfänglich unverändert, da sich bis SaveChanges nicht überlappend ausgeführt werdenPosts initially remain Unchanged since cascades do not happen until SaveChanges
  • Da beschränken teilt EF auf die '-fk ' nicht automatisch auf null festlegen, bleibt es ungleich Null und SaveChanges löst aus, ohne zu speichernSince Restrict tells EF to not automatically set the FK to null, it remains non-null and SaveChanges throws without saving

Beispiele für die verwaisten Objekte löschenDelete orphans examples

Der folgende Code ist Teil einer Beispiel , kann eine Ausführung heruntergeladen werden.The code below is part of a sample that can be downloaded an run. Im Beispiel wird gezeigt, was geschieht, für jede Löschverhalten für optionale und notwendige Beziehungen, wenn die Beziehung zwischen einem übergeordneten/Prinzipal und seine untergeordneten Elemente/Dependents unterbrochen wird.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. In diesem Beispiel wird die Beziehung abgetrennt werden durch das Entfernen der abhängigen Elemente/untergeordnete Elemente (Beiträge) aus der auflistungsnavigationseigenschaft für den Prinzipal/im übergeordneten Element (Blog).In this example, the relationship is severed by removing the dependents/children (posts) from the collection navigation property on the principal/parent (blog). Allerdings ist das Verhalten identisch, wenn der Verweis von abhängigen und untergeordneten Elementen auf Prinzipal/im übergeordneten Element stattdessen out gelöscht wird.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)}");
}

Wir führen Sie durch jede Variante zu verstehen, was geschieht.Let's walk through each variation to understand what is happening.

DeleteBehavior.Cascade mit erforderlichen oder optionalen BeziehungDeleteBehavior.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 '1' 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 '1' 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 '1' is in state Detached with FK '1' and no reference to a blog.
  • Beiträge werden als geändert markiert, da das Trennen der Beziehung der FK als null markiert sein verursacht werden.Posts are marked as Modified because severing the relationship caused the FK to be marked as null
    • Ist der Fremdschlüssel keine NULL-Werte zulässt, klicken Sie dann ändert der tatsächliche Wert sich nicht, obwohl sie als null markiert istIf the FK is not nullable, then the actual value will not change even though it is marked as null
  • SaveChanges sendet löschungen für abhängige Dateien/untergeordnete Elemente (Beiträge)SaveChanges sends deletes for dependents/children (posts)
  • Nach dem Speichern, werden die abhängigen Elemente/untergeordneten Elemente (Beiträge) getrennt, da sie jetzt aus der Datenbank gelöscht wurdenAfter saving, the dependents/children (posts) are detached since they have now been deleted from the database

DeleteBehavior.ClientSetNull oder DeleteBehavior.SetNull mit erforderliche BeziehungDeleteBehavior.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 '1' 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 '1' 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.
  • Beiträge werden als geändert markiert, da das Trennen der Beziehung der FK als null markiert sein verursacht werden.Posts are marked as Modified because severing the relationship caused the FK to be marked as null
    • Ist der Fremdschlüssel keine NULL-Werte zulässt, klicken Sie dann ändert der tatsächliche Wert sich nicht, obwohl sie als null markiert istIf the FK is not nullable, then the actual value will not change even though it is marked as null
  • SaveChanges versucht Post-FK auf null festgelegt, aber dies schlägt fehl, da die '-fk ' nicht auf NULL festlegbar ist.SaveChanges attempts to set the post FK to null, but this fails because the FK is not nullable

DeleteBehavior.ClientSetNull oder DeleteBehavior.SetNull mit optionale BeziehungDeleteBehavior.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 '1' 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 '1' 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 '1' is in state Unchanged with FK 'null' and no reference to a blog.
  • Beiträge werden als geändert markiert, da das Trennen der Beziehung der FK als null markiert sein verursacht werden.Posts are marked as Modified because severing the relationship caused the FK to be marked as null
    • Ist der Fremdschlüssel keine NULL-Werte zulässt, klicken Sie dann ändert der tatsächliche Wert sich nicht, obwohl sie als null markiert istIf the FK is not nullable, then the actual value will not change even though it is marked as null
  • SaveChanges legt die FK der abhängigen Elemente/untergeordnete Elemente (Beiträge) auf null fest.SaveChanges sets the FK of both dependents/children (posts) to null
  • Nach dem Speichern, die abhängigen Elemente/untergeordneten Elemente (Beiträge) jetzt Nullwerte FK haben und ihre Verweis auf die gelöschte Prinzipal/im übergeordneten Element (Blog) entfernt wurdeAfter saving, the dependents/children (posts) now have null FK values and their reference to the deleted principal/parent (blog) has been removed

DeleteBehavior.Restrict mit erforderlichen oder optionalen BeziehungDeleteBehavior.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 '1' 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 '1' 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.
  • Beiträge werden als geändert markiert, da das Trennen der Beziehung der FK als null markiert sein verursacht werden.Posts are marked as Modified because severing the relationship caused the FK to be marked as null
    • Ist der Fremdschlüssel keine NULL-Werte zulässt, klicken Sie dann ändert der tatsächliche Wert sich nicht, obwohl sie als null markiert istIf the FK is not nullable, then the actual value will not change even though it is marked as null
  • Da beschränken teilt EF auf die '-fk ' nicht automatisch auf null festlegen, bleibt es ungleich Null und SaveChanges löst aus, ohne zu speichernSince Restrict tells EF to not automatically set the FK to null, it remains non-null and SaveChanges throws without saving

Kaskadierende verfolgte EntitätenCascading to untracked entities

Beim Aufruf SaveChanges, die Delete Cascade-Regeln gelten für alle Entitäten, die vom Kontext nachverfolgt werden.When you call SaveChanges, the cascade delete rules will be applied to any entities that are being tracked by the context. Dies ist die Situation, in der alle oben genannten Beispiele, ist SQL zum Löschen der Prinzipal/im übergeordneten Element (Blog) und alle abhängigen Elemente/untergeordneten Elemente (Beiträge) generiert wurde: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

Wenn nur der Prinzipalserver geladen – ist z. B. wenn eine Abfrage erfolgt für einen Blog ohne eine Include(b => b.Posts) auch Beiträge--enthalten dann SaveChanges generiert nur SQL aus, um den Prinzipal/im übergeordneten Element löschen: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

Die abhängigen Elemente/untergeordneten Elemente (Beiträge) wird nur gelöscht werden, wenn die Datenbank eine entsprechende überlappungsverhalten konfiguriert wurde.The dependents/children (posts) will only be deleted if the database has a corresponding cascade behavior configured. Wenn Sie EF verwenden, um die Datenbank zu erstellen, wird dieses Verhalten Cascade für Sie eingerichtet werden.If you use EF to create the database, this cascade behavior will be setup for you.