Beziehungen, Navigations Eigenschaften und FremdschlüsselRelationships, navigation properties, and foreign keys

Dieser Artikel bietet einen Überblick darüber, wie Entity Framework Beziehungen zwischen Entitäten verwaltet.This article gives an overview of how Entity Framework manages relationships between entities. Außerdem erhalten Sie eine Anleitung zum Zuordnen und Bearbeiten von Beziehungen.It also gives some guidance on how to map and manipulate relationships.

Beziehungen in EFRelationships in EF

In relationalen Datenbanken werden Beziehungen (auch als Zuordnungen bezeichnet) zwischen Tabellen durch Fremdschlüssel definiert.In relational databases, relationships (also called associations) between tables are defined through foreign keys. Ein Fremdschlüssel (FS) ist eine Spalte oder eine Kombination von Spalten, mit deren Hilfe ein Link zwischen den Daten in zwei Tabellen eingerichtet und erzwungen wird.A foreign key (FK) is a column or combination of columns that is used to establish and enforce a link between the data in two tables. Im Allgemeinen gibt es drei Typen von Beziehungen: eins-zu-eins, 1: n und m:n-.There are generally three types of relationships: one-to-one, one-to-many, and many-to-many. In einer 1: n-Beziehung wird der Fremdschlüssel für die Tabelle definiert, die das viele Ende der Beziehung darstellt.In a one-to-many relationship, the foreign key is defined on the table that represents the many end of the relationship. Die m:n-Beziehung umfasst das Definieren einer dritten Tabelle (als Verknüpfung oder jointabelle bezeichnet), deren Primärschlüssel aus den Fremdschlüsseln aus beiden verknüpften Tabellen besteht.The many-to-many relationship involves defining a third table (called a junction or join table), whose primary key is composed of the foreign keys from both related tables. In einer eins-zu-eins-Beziehung agiert der Primärschlüssel zusätzlich als Fremdschlüssel, und für beide Tabellen gibt es keine separate Fremdschlüssel Spalte.In a one-to-one relationship, the primary key acts additionally as a foreign key and there is no separate foreign key column for either table.

Die folgende Abbildung zeigt zwei Tabellen, die an einer 1: n-Beziehung beteiligt sind.The following image shows two tables that participate in one-to-many relationship. Die Kurs Tabelle ist die abhängige Tabelle, da Sie die DepartmentID -Spalte enthält, die Sie mit der Abteilungs Tabelle verknüpft.The Course table is the dependent table because it contains the DepartmentID column that links it to the Department table.

Abteilungs-und Kurs Tabellen

In Entity Framework kann eine Entität über eine Zuordnung oder Beziehung mit anderen Entitäten verknüpft werden.In Entity Framework, an entity can be related to other entities through an association or relationship. Jede Beziehung enthält zwei Enden, die den Entitätstyp und die Multiplizität des Typs (1, 0 oder 1 oder viele) für die beiden Entitäten in dieser Beziehung beschreiben.Each relationship contains two ends that describe the entity type and the multiplicity of the type (one, zero-or-one, or many) for the two entities in that relationship. Die Beziehung wird möglicherweise von einer referenziellen Einschränkung geregelt, die beschreibt, welches Ende der Beziehung die Prinzipalrolle und welches die abhängige Rolle ist.The relationship may be governed by a referential constraint, which describes which end in the relationship is a principal role and which is a dependent role.

Navigations Eigenschaften bieten eine Möglichkeit, eine Zuordnung zwischen zwei Entitäts Typen zu navigieren.Navigation properties provide a way to navigate an association between two entity types. Jedes Objekt kann für jede Beziehung, an der es beteiligt ist, über eine Navigationseigenschaft verfügen.Every object can have a navigation property for every relationship in which it participates. Mithilfe von Navigations Eigenschaften können Sie Beziehungen in beiden Richtungen navigieren und verwalten, wobei entweder ein Verweis Objekt (wenn die Multiplizität entweder 1 oder 0 ist) oder eine Auflistung (wenn die Multiplizität viele ist) zurückgegeben werden.Navigation properties allow you to navigate and manage relationships in both directions, returning either a reference object (if the multiplicity is either one or zero-or-one) or a collection (if the multiplicity is many). Sie haben auch die Möglichkeit, eine unidirektionale Navigation zu wählen. in diesem Fall definieren Sie die Navigations Eigenschaft nur für einen Typ, der an der Beziehung teilnimmt, nicht für beides.You may also choose to have one-way navigation, in which case you define the navigation property on only one of the types that participates in the relationship and not on both.

Es wird empfohlen, Eigenschaften in das Modell einzuschließen, die Fremdschlüsseln in der Datenbank zugeordnet werden.It is recommended to include properties in the model that map to foreign keys in the database. Wenn Fremdschlüsseleigenschaften einbezogen wurden, können Sie durch das Ändern des Fremdschlüsselwerts für ein abhängiges Objekt eine Beziehung erstellen oder ändern.With foreign key properties included, you can create or change a relationship by modifying the foreign key value on a dependent object. Diese Art von Zuordnung wird Fremdschlüsselzuordnung genannt.This kind of association is called a foreign key association. Die Verwendung von Fremdschlüsseln ist noch wichtiger, wenn Sie mit getrennten Entitäten arbeiten.Using foreign keys is even more essential when working with disconnected entities. Beachten Sie, dass bei der Arbeit mit 1-zu-1 oder 1-zu-0. 1 Beziehungen, es gibt keine separate Fremdschlüssel Spalte, die Primärschlüssel Eigenschaft fungiert als Fremdschlüssel und ist immer im Modell enthalten.Note, that when working with 1-to-1 or 1-to-0..1 relationships, there is no separate foreign key column, the primary key property acts as the foreign key and is always included in the model.

Wenn Fremdschlüssel Spalten nicht im Modell enthalten sind, werden die Zuordnungs Informationen als unabhängiges Objekt verwaltet.When foreign key columns are not included in the model, the association information is managed as an independent object. Beziehungen werden über Objekt Verweise anstelle von Fremdschlüssel Eigenschaften nachverfolgt.Relationships are tracked through object references instead of foreign key properties. Diese Art von Zuordnung wird als unabhängigeZuordnung bezeichnet.This type of association is called an independent association. Die gängigste Methode zum Ändern einer unabhängigen Zuordnung besteht darin, die Navigations Eigenschaften zu ändern, die für jede Entität generiert werden, die an der Zuordnung teilnimmt.The most common way to modify an independent association is to modify the navigation properties that are generated for each entity that participates in the association.

Sie können wahlweise einen oder beide Zuordnungstypen im Modell verwenden.You can choose to use one or both types of associations in your model. Wenn Sie jedoch über eine reine m:n-Beziehung verfügen, die durch eine Verknüpfungs Tabelle verbunden ist, die nur Fremdschlüssel enthält, verwendet das EF eine unabhängige Zuordnung, um eine m:n-Beziehung zu verwalten.However, if you have a pure many-to-many relationship that is connected by a join table that contains only foreign keys, the EF will use an independent association to manage such many-to-many relationship.   

Die folgende Abbildung zeigt ein konzeptionelles Modell, das mit dem Entity Framework Designer erstellt wurde.The following image shows a conceptual model that was created with the Entity Framework Designer. Das Modell enthält zwei Entitäten, die an einer 1: n-Beziehung beteiligt sind.The model contains two entities that participate in one-to-many relationship. Beide Entitäten verfügen über Navigations Eigenschaften.Both entities have navigation properties. Course ist die abhängige Entität, und die Eigenschaft " DepartmentID Foreign Key" ist definiert.Course is the dependent entity and has the DepartmentID foreign key property defined.

Abteilungs-und Kurs Tabellen mit Navigations Eigenschaften

Der folgende Code Ausschnitt zeigt das gleiche Modell, das mit Code First erstellt wurde.The following code snippet shows the same model that was created with Code First.

public class Course
{
  public int CourseID { get; set; }
  public string Title { get; set; }
  public int Credits { get; set; }
  public int DepartmentID { get; set; }
  public virtual Department Department { get; set; }
}

public class Department
{
   public Department()
   {
     this.Courses = new HashSet<Course>();
   }  
   public int DepartmentID { get; set; }
   public string Name { get; set; }
   public decimal Budget { get; set; }
   public DateTime StartDate { get; set; }
   public int? Administrator {get ; set; }
   public virtual ICollection<Course> Courses { get; set; }
}

Konfigurieren oder Mapping von BeziehungenConfiguring or mapping relationships

Im restlichen Abschnitt wird erläutert, wie Sie mithilfe von Beziehungen auf Daten zugreifen und diese bearbeiten.The rest of this page covers how to access and manipulate data using relationships. Informationen zum Einrichten von Beziehungen in Ihrem Modell finden Sie auf den folgenden Seiten.For information on setting up relationships in your model, see the following pages.

Erstellen und Ändern von BeziehungenCreating and modifying relationships

Wenn Sie in einer FremdschlüsselZuordnung die Beziehung ändern, wird der Status eines abhängigen Objekts mit einem- EntityState.Unchanged Zustand in geändert EntityState.Modified .In a foreign key association, when you change the relationship, the state of a dependent object with an EntityState.Unchanged state changes to EntityState.Modified. In einer unabhängigen Beziehung wird durch das Ändern der Beziehung der Zustand des abhängigen Objekts nicht aktualisiert.In an independent relationship, changing the relationship does not update the state of the dependent object.

In den folgenden Beispielen wird gezeigt, wie die Fremdschlüssel Eigenschaften und Navigations Eigenschaften verwendet werden, um die zugehörigen Objekte zuzuordnen.The following examples show how to use the foreign key properties and navigation properties to associate the related objects. Mit Fremdschlüssel Zuordnungen können Sie eine der beiden Methoden verwenden, um Beziehungen zu ändern, zu erstellen oder zu ändern.With foreign key associations, you can use either method to change, create, or modify relationships. Bei unabhängigen Zuordnungen können Sie die Fremdschlüsseleigenschaft nicht verwenden.With independent associations, you cannot use the foreign key property.

  • Durch Zuweisen eines neuen Werts zu einer Fremdschlüssel Eigenschaft, wie im folgenden Beispiel gezeigt.By assigning a new value to a foreign key property, as in the following example.

    course.DepartmentID = newCourse.DepartmentID;
    
  • Mit dem folgenden Code wird eine Beziehung entfernt, indem der Fremdschlüssel auf nullfestgelegt wird.The following code removes a relationship by setting the foreign key to null. Beachten Sie, dass die Fremdschlüssel Eigenschaft NULL-Werte zulassen muss.Note, that the foreign key property must be nullable.

    course.DepartmentID = null;
    

    Hinweis

    Wenn sich der Verweis im hinzugefügten Zustand befindet (in diesem Beispiel das Kurs Objekt), wird die Verweis Navigations Eigenschaft nicht mit den Schlüsselwerten eines neuen Objekts synchronisiert, bis SaveChanges aufgerufen wird.If the reference is in the added state (in this example, the course object), the reference navigation property will not be synchronized with the key values of a new object until SaveChanges is called. Es findet keine Synchronisierung statt, da der Objektkontext erst dann permanente Schlüssel für hinzugefügte Objekte enthält, wenn diese gespeichert werden.Synchronization does not occur because the object context does not contain permanent keys for added objects until they are saved. Wenn neue Objekte vollständig synchronisiert werden müssen, sobald Sie die Beziehung festgelegt haben, verwenden Sie eine der folgenden Methoden. *If you must have new objects fully synchronized as soon as you set the relationship, use one of the following methods.*

  • Durch das Zuweisen einer Navigationseigenschaft zu einem neuen Objekt.By assigning a new object to a navigation property. Mit dem folgenden Code wird eine Beziehung zwischen einem Kurs und einem erstellt department .The following code creates a relationship between a course and a department. Wenn die Objekte an den Kontext angefügt werden, course wird auch der-Auflistung hinzugefügt department.Courses , und die entsprechende Fremdschlüssel Eigenschaft für das- course Objekt wird auf den Schlüssel Eigenschafts Wert der Abteilung festgelegt.If the objects are attached to the context, the course is also added to the department.Courses collection, and the corresponding foreign key property on the course object is set to the key property value of the department.

    course.Department = department;
    
  • Legen Sie die-Navigations Eigenschaft auf fest, um die Beziehung zu löschen null .To delete the relationship, set the navigation property to null. Wenn Sie mit Entity Framework arbeiten, die auf .NET 4,0 basiert, muss das verknüpfte Ende geladen werden, bevor Sie es auf NULL festlegen.If you are working with Entity Framework that is based on .NET 4.0, then the related end needs to be loaded before you set it to null. Beispiel:For example:

    context.Entry(course).Reference(c => c.Department).Load();
    course.Department = null;
    

    Beginnend mit Entity Framework 5,0, das auf .NET 4,5 basiert, können Sie die Beziehung auf NULL festlegen, ohne das verknüpfte Ende zu laden.Starting with Entity Framework 5.0, that is based on .NET 4.5, you can set the relationship to null without loading the related end. Sie können den aktuellen Wert auch mit der folgenden Methode auf NULL festlegen.You can also set the current value to null using the following method.

    context.Entry(course).Reference(c => c.Department).CurrentValue = null;
    
  • Durch das Löschen eines Objekts aus einer Entitätsauflistung oder das Hinzufügen eines Objekts zu einer Entitätsauflistung.By deleting or adding an object in an entity collection. Beispielsweise können Sie der Auflistung ein Objekt vom Typ hinzufügen Course department.Courses .For example, you can add an object of type Course to the department.Courses collection. Mit diesem Vorgang wird eine Beziehung zwischen einem bestimmten Kurs und einem bestimmten erstellt department .This operation creates a relationship between a particular course and a particular department. Wenn die Objekte an den Kontext angefügt werden, werden der Abteilungs Verweis und die Fremdschlüssel Eigenschaft des Kurs Objekts auf den entsprechenden festgelegt department .If the objects are attached to the context, the department reference and the foreign key property on the course object will be set to the appropriate department.

    department.Courses.Add(newCourse);
    
  • Mithilfe der- ChangeRelationshipState Methode können Sie den Zustand der angegebenen Beziehung zwischen zwei Entitäts Objekten ändern.By using the ChangeRelationshipState method to change the state of the specified relationship between two entity objects. Diese Methode wird am häufigsten bei der Arbeit mit N-Tier-Anwendungen und einer unabhängigen Zuordnung verwendet (Sie kann nicht mit einer Fremdschlüssel Zuordnung verwendet werden).This method is most commonly used when working with N-Tier applications and an independent association (it cannot be used with a foreign key association). Um diese Methode verwenden zu können, müssen Sie auch auf festlegen ObjectContext , wie im folgenden Beispiel gezeigt.Also, to use this method you must drop down to ObjectContext, as shown in the example below.
    Im folgenden Beispiel gibt es eine m:n-Beziehung zwischen Dozenten und Kursen.In the following example, there is a many-to-many relationship between Instructors and Courses. Durch Aufrufen der ChangeRelationshipState -Methode und übergeben des- EntityState.Added Parameters weiß das, SchoolContext dass eine Beziehung zwischen den beiden-Objekten hinzugefügt wurde:Calling the ChangeRelationshipState method and passing the EntityState.Added parameter, lets the SchoolContext know that a relationship has been added between the two objects:

    
    ((IObjectContextAdapter)context).ObjectContext.
      ObjectStateManager.
      ChangeRelationshipState(course, instructor, c => c.Instructor, EntityState.Added);
    

    Beachten Sie Folgendes: Wenn Sie eine Beziehung aktualisieren (nicht nur hinzufügen), müssen Sie die alte Beziehung löschen, nachdem Sie die neue Beziehung hinzugefügt haben:Note that if you are updating (not just adding) a relationship, you must delete the old relationship after adding the new one:

    ((IObjectContextAdapter)context).ObjectContext.
      ObjectStateManager.
      ChangeRelationshipState(course, oldInstructor, c => c.Instructor, EntityState.Deleted);
    

Synchronisieren der Änderungen zwischen den Fremdschlüsseln und den Navigations EigenschaftenSynchronizing the changes between the foreign keys and navigation properties

Wenn Sie die Beziehung der Objekte ändern, die mit einer der oben beschriebenen Methoden an den Kontext angefügt sind, müssen Entity Framework Fremdschlüssel, Verweise und Auflistungen synchron halten. Entity Framework diese Synchronisierung (auch als Beziehungs Korrektur bezeichnet) für die poco-Entitäten mit Proxys automatisch verwaltet.When you change the relationship of the objects attached to the context by using one of the methods described above, Entity Framework needs to keep foreign keys, references, and collections in sync. Entity Framework automatically manages this synchronization (also known as relationship fix-up) for the POCO entities with proxies. Weitere Informationen finden Sie unter Arbeiten mitProxys.For more information, see Working with Proxies.

Wenn Sie poco-Entitäten ohne Proxys verwenden, müssen Sie sicherstellen, dass die DetectChanges -Methode aufgerufen wird, um die zugehörigen Objekte im Kontext zu synchronisieren.If you are using POCO entities without proxies, you must make sure that the DetectChanges method is called to synchronize the related objects in the context. Beachten Sie, dass die folgenden APIs automatisch einen DetectChanges -Befehl auslöst.Note that the following APIs automatically trigger a DetectChanges call.

  • DbSet.Add
  • DbSet.AddRange
  • DbSet.Remove
  • DbSet.RemoveRange
  • DbSet.Find
  • DbSet.Local
  • DbContext.SaveChanges
  • DbSet.Attach
  • DbContext.GetValidationErrors
  • DbContext.Entry
  • DbChangeTracker.Entries
  • Ausführen einer LINQ-Abfrage für eine DbSetExecuting a LINQ query against a DbSet

In Entity Framework Sie häufig Navigations Eigenschaften verwenden, um Entitäten zu laden, die mit der zurückgegebenen Entität von der definierten Zuordnung verknüpft sind.In Entity Framework you commonly use navigation properties to load entities that are related to the returned entity by the defined association. Weitere Informationen finden Sie unter Laden verwandter Objekte.For more information, see Loading Related Objects.

Hinweis

Wenn Sie in einer Fremdschlüsselzuordnung ein verknüpftes Ende eines abhängigen Objekts laden, wird das verknüpfte Objekt auf der Grundlage des Fremdschlüsselwerts des abhängigen Elements geladen, der sich gerade im Arbeitsspeicher befindet:In a foreign key association, when you load a related end of a dependent object, the related object will be loaded based on the foreign key value of the dependent that is currently in memory:

    // Get the course where currently DepartmentID = 2.
    Course course = context.Courses.First(c => c.DepartmentID == 2);

    // Use DepartmentID foreign key property
    // to change the association.
    course.DepartmentID = 3;

    // Load the related Department where DepartmentID = 3
    context.Entry(course).Reference(c => c.Department).Load();

In einer unabhängigen Zuordnung wird das verknüpfte Ende eines abhängigen Objekts auf der Grundlage des Fremdschlüsselwerts abgefragt, der sich gerade in der Datenbank befindet.In an independent association, the related end of a dependent object is queried based on the foreign key value that is currently in the database. Wenn jedoch die Beziehung geändert wurde und die Verweis Eigenschaft des abhängigen Objekts auf ein anderes Prinzipal Objekt verweist, das in den Objekt Kontext geladen wird, wird Entity Framework versucht, eine Beziehung zu erstellen, die auf dem Client definiert ist.However, if the relationship was modified, and the reference property on the dependent object points to a different principal object that is loaded in the object context, Entity Framework will try to create a relationship as it is defined on the client.

Verwalten von NebenläufigkeitManaging concurrency

Sowohl in Fremdschlüssel-als auch in unabhängigen Zuordnungen basieren Parallelitäts Überprüfungen auf den Entitäts Schlüsseln und anderen Entitäts Eigenschaften, die im Modell definiert sind.In both foreign key and independent associations, concurrency checks are based on the entity keys and other entity properties that are defined in the model. Wenn Sie den EF-Designer verwenden, um ein Modell zu erstellen, legen Sie das- ConcurrencyMode Attribut auf fest , um anzugeben, dass die-Eigenschaft auf Parallelität geprüft werden soll.When using the EF Designer to create a model, set the ConcurrencyMode attribute to fixed to specify that the property should be checked for concurrency. Wenn Sie Code First verwenden, um ein Modell zu definieren, verwenden Sie die-Anmerkung für Eigenschaften, die auf Parallelität ConcurrencyCheck geprüft werden sollen.When using Code First to define a model, use the ConcurrencyCheck annotation on properties that you want to be checked for concurrency. Wenn Sie mit Code First arbeiten, können Sie auch die-Anmerkung verwenden TimeStamp , um anzugeben, dass die-Eigenschaft auf Parallelität geprüft werden soll.When working with Code First you can also use the TimeStamp annotation to specify that the property should be checked for concurrency. In einer bestimmten Klasse kann nur eine Zeitstempel-Eigenschaft vorhanden sein.You can have only one timestamp property in a given class. Code First ordnet diese Eigenschaft einem Feld, das keine NULL-Werte zulässt, in der Datenbank zu.Code First maps this property to a non-nullable field in the database.

Es wird empfohlen, bei der Arbeit mit Entitäten, die an der Parallelitäts Überprüfung und-Auflösung beteiligt sind, stets die Fremdschlüssel Zuordnung zu verwenden.We recommend that you always use the foreign key association when working with entities that participate in concurrency checking and resolution.

Weitere Informationen finden Sie unter behandelnvon Parallelitäts Konflikten.For more information, see Handling Concurrency Conflicts.

Arbeiten mit überlappenden SchlüsselnWorking with overlapping Keys

Überlappende Schlüssel sind zusammengesetzte Schlüssel, wobei einige Eigenschaften eines Schlüssels auch Teil eines anderen Schlüssels der Entität sind.Overlapping keys are composite keys where some properties in the key are also part of another key in the entity. Unabhängige Zuordnungen können keine überlappenden Schlüssel enthalten.You cannot have an overlapping key in an independent association. Um eine Fremdschlüsselzuordnung zu ändern, die überlappende Schlüssel enthält, empfiehlt es sich, die Fremdschlüsselwerte zu ändern, statt die Objektverweise zu verwenden.To change a foreign key association that includes overlapping keys, we recommend that you modify the foreign key values instead of using the object references.