Up Query using property navigation

Adding and Removing Related Objects

Last modified on October 21, 2011 12:47

Navigation properties that return collections (e.g., anEmployee.Orders) are always of the type RelatedEntityList<T>. The RelatedEntityList in turn provides Add and Remove methods that may be used to add or remove related entities.



Add()

The Add() method takes a parameter of the type contained by the collection (e.g., an Order).

C#
Order anOrder = new Order();
anOrder.OrderDate = DateTime.Today;
anOrder.FreightCost = Convert.ToDecimal(999.99);
anEmployee.Orders.Add(anOrder);
VB
Dim anOrder As New Order()
anOrder.OrderDate = Date.Today
anOrder.FreightCost = Convert.ToDecimal(999.99)
anEmployee.Orders.Add(anOrder)

Invoking Add() adds the supplied item to the collection. If the relation between the parent and child types is 1-to-many and the supplied item is currently associated with a different parent, then Add() simultaneously removes it from the corresponding collection of the other parent. The equivalent result on table rows in a relational database is that the child entity’s foreign key value is changed. 

Note that, in the above snippet, we did not need to set the SalesRep property of the new Order to the Employee whom we wanted to become its parent:
C#
// anOrder.SalesRep = anEmployee; //don't need this; Add() will handle it
VB
anOrder.SalesRep = anEmployee '' don't need this; Add() will handle it

Invocation of the Add() method on anEmployee.Orders produced the equivalent result.

Remove()

Remove() also takes a parameter of the type contained by the collection. It dissociates the indicated instance from the collection’s parent. Speaking again of the equivalent result on table rows in a relational database, the child entity’s foreign key value is set to null.

C#
anEmployee.Orders.Remove(anOrder);
VB
anEmployee.Orders.Remove(anOrder)

Note that while Remove unassigns the Order from the target Employee, removing it from the collection returned by the navigation property, it does not remove it from the cache or mark it for deletion. If you want the Order removed from the cache or deleted from the back-end datastore, you must order those actions separately by calling the Order’s EntityAspect.Remove()or EntityAspect.Delete() methods, as appropriate.

Add() and Remove () on many-to-many navigation properties

You can also use Add() and Remove () on many-to-many navigation collections generated by the Entity Data Model. You get these in your Entity Data Model when two entities are linked by a many-to-many linking table that has "no payload"; that is, no columns other than the two foreign keys (which also form a composite primary key). An example would be an Employee linked to a Territory by means of an EmployeeTerritory table whose composite primary key consists of the two foreign keys EmployeeId and TerritoryId, and which has no other columns.

When you have such an association, invoking Add() on the many-to-many navigation property creates (in the EntityManager cache) the necessary linking object in the EntitySet for the linking objects. Note that those objects are not exposed in the conceptual model, and are never manipulated directly by you. Remove() marks as deleted the linking object that formerly connected the two entities in the many-to-many relationship. Both changes – the insertion of a new linking object or the deletion of an existing one – are propagated to the back-end data store upon the execution of SaveChanges() on the governing EntityManager.

Adding and removing items in custom-coded many-to-many navigation properties

You can (and probably will) also have in your model many-to-many associations involving linking entities that do have payload. (For example, in the NorthwindIB database, Order links Employees (who act as sales reps) to Customers in a many-to-many relationship.) For these cases, you should add and remove elements to the m-to-m collection (e.g., anEmployee.Customers) by inserting or deleting instances of the linking entity. Since that linking entity is probably significant in its own right (again consider an Order), it likely has properties that need their values set at creation time in any case.

For example, the following code will have the indirect effect of adding a new Customer to the Customers collection of anEmployee, but only if the Order being added is for a Customer with which anEmployee is not already linked through some other Order. Otherwise, aCustomer is already in anEmployee’s Customers collection.
(Note: Create is a static method on the Order partial class that the developer extends)

C#
// May add a Customer to anEmployee’s Customers collection
anOrder = Order.Create(_entityManager, aCustomer, anOrderDate);
anEmployee.Orders.Add(anOrder);
VB
' May add a Customer to anEmployee’s Customers collection
anOrder = Order.Create(_entityManager, aCustomer, anOrderDate)
anEmployee.Orders.Add(anOrder)

Similarly, the following code will have the indirect effect of removing aCustomer from the Customers collection of anEmployee, but only if anEmployee has no other Orders for aCustomer. If she does, then aCustomer will remain in her Customers collection.

C#
// May remove a Customer from anEmployee’s Customers collection
anOrder.EntityAspect.Delete();
VB
' May remove a Customer from anEmployee’s Customers collection
anOrder.EntityAspect.Delete()
Created by DevForce on December 09, 2010 16:05

This wiki is licensed under a Creative Commons 2.0 license. XWiki Enterprise 3.2 - Documentation. Copyright © 2012 IdeaBlade