[This topic is pre-release documentation and is subject to change in future releases. Blank topics are included as placeholders.]
In the Entity Framework, an entity can be related to other entities through an association. This relationship between entities is defined in the conceptual model by the Association element. Each relationship contains two ends that describe the entity type and the multiplicity of the type (one, zero-or-one, or many). 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.
Starting with the .NET Framework version 4, you can include foreign keys in the conceptual model. The Include Foreign Key Columns option in the Entity Data Model Wizard is selected by default. When this option is selected, the generated entity objects have scalar properties that map to foreign key columns. With foreign key properties included, you can create or change a relationship by modifying the foreign key value on a dependent object. This kind of association is called a foreign key association.
When foreign key columns are not included in the conceptual model, the association information is managed as an independent object. Relationships are tracked through object references instead of foreign key properties, and are represented as an ObjectStateEntry object in the ObjectStateManager.This type of association is called an independent association. 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.
In both types of associations, every object can have a navigation property for every relationship in which it participates. The navigation properties allow you to navigate and manage relationships in both directions, returning either a reference object, if the multiplicity is zero-or-one, or a collection of objects, if the multiplicity is many.
Creating and Modifying Relationships
In the Entity Framework, you can create and modify relationships in several ways.
-
By assigning a new object to a navigation property.
-
By deleting or adding an object in an entity collection. For example, you can use the Add method to add order objects to the EntityCollection of the customer object, which creates a relationship between a particular order and customer:
customer.Orders.Add(order)
-
In foreign key associations, you can assign a new value to a foreign key property, as in the following example:
order.CustomerID = newCustomer.CustomerID
order.CustomerID = null
-
By changing the reference value of the entity.
order.CustomerReference.Value = anotherNewCustomer
-
By creating the entity key for a specific object. If the object with this key already exists in the object context, the >CreateEntityKey method will return the EntityKey of the existing object.
order.CustomerReference.EntityKey = ctx.CreateEntityKey("EntitySetName", newObject)
The Entity Framework needs to keep foreign keys, references, and collections in sync. The Entity Framework will manage this synchronization for certain types of eligible objects:
If you are using persistence-ignorant objects without proxies, you must manually manage the synchronization when you work with disconnected objects, or you can call the DetectChanges method to synchronize the property values of persistence-ignorant objects with the ObjectStateManager.
Working with Overlapping Keys
Overlapping keys are composite keys where some properties in the key are also part of another key in the entity. You cannot have an overlapping key in an independent association. 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.
Loading Related Objects
In an independent association, when you load the related end of an object, the related object loaded based on the foreign key value of the dependent that is currently in the database and not the one in memory. This means that after the call to EntityReference.Load, the EntityReference still does not refer to the value of the newly-queried object. The following example will not load the Address with ID 26, but the address that SalesOrderHeader is associated with in the database:
SalesOrderHeader order =
context.SalesOrderHeaders.Single(o => o.SalesOrderID == orderId);
order.Address1Reference.EntityKey =
new System.Data.EntityKey("AdventureWorksEntities.Addresses", "AddressID", 26);
order.Address1Reference.Load();
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 order where currently AddressID = 1.
SalesOrderHeader order = context.SalesOrderHeaders.First(o=>o.SalesOrderID == orderId);
// Use BillToAddressID foreign key property
// to change the association.
order.BillToAddressID = 2
order.AddressReference.Load();
Considerations for Identifying and Non-identifying Relationships
When a primary key of the principal entity is also part of the primary key of the dependent entity, the relationship is an identifying relationship. In an identifying relationship the dependent entity cannot exist without the principal entity. This constraint causes the following behaviors in an identifying relationship:
-
Deleting the principal object also deletes the dependent object. This is the same behavior as specifying <OnDelete Action="Cascade" /> in the model for the relationship.
-
Removing the relationship deletes the dependent object. Calling the Remove method on the EntityCollection marks both the relationship and the dependent object for deletion.
-
When you create a new dependent object, the principal object must exist in the object context or in the data source before you call SaveChanges. If the principal object does not exist, an InvalidOperationException will be raised.
In a non-identifying relationship, deleting the principal object will not delete the dependent object. When you delete a principal object, you must manually delete the dependent object or assign a new principal object to the dependent object. Alternatively, you can specify <OnDelete Action="Cascade" /> in the model to ensure that dependent objects are deleted when you delete the related principal object.
In This Section
See Also