Up Save
DevForce 2010 Resource Center » DevForce development » Save » Save a graph of entities

Save a graph of entities

Last modified on August 15, 2012 17:20

When performing a save where you specify exactly which entities should be saved, it is often useful to be able to 'walk' a selected 'graph' of entities related to those that you know you are saving in order to determine if any other 'related' entities that need to be saved as well.

This could be accomplished by 

  • 1) Iterating over each of the 'root' entities that you wish to save 
  • 2) For each of these entities iterating over each of the navigation properties that constitute your selected graph
  • 3) For each of these navigation properties, perform the navigation, using a CacheOnly FetchStrategy to insure that no 'additional' entities are added to the local cache as a result of this operation.
  • 4) For only those entities returned from the navigation that have an EntityState that is either Added, Modified or Deleted.
  • 5) Accumulated these for our eventual result.
  • 6) Repeat step 2 above for each these entities.

But there is an easier way!  The EntityManager.FindEntityGraph method does precisely this.



Using the FindEntityGraph method

The EntityManager.FindEntityGraph method is specifically intended to be used to search the local cache for any entities that are navigable from a list of root entities according to a specified graph.

C#
public IList<Object> FindEntityGraph(
  IEnumerable roots,
  IEnumerable<EntitySpan> spans,
  EntityState entityState);
VB
public IList(Of Object) FindEntityGraph(
  IEnumerable roots, _
  IEnumerable(Of EntitySpan) spans, _
  EntityState entityState)

Given any entity or entities in a graph, this method collects and retrieves all of the related entities in the graph. This is a cache-only operation.

ParameterDescription
roots A list of entities used as the starting point for retrieving all other related entities. 
spans One or more EntitySpans; this defines the graph to be traversed. An error will be thown for any span that does not have a matching type in one of the roots.
entityState The EntityState of entities to return.  This allows you to filter by EntityState.

An example of its use is shown below:

C#
// Get the root(s).
var roots = listOfEmployeesToSave;

// Get the span(s).
var spans = new List<EntitySpan> {
 new EntitySpan(typeof(Employee), EntityRelations.FK_OrderSummary_Employee,
    EntityRelations.FK_Order_Details_Orders, EntityRelations.FK_Order_Details_Products)
};

// Find the related entities.
var entityState = EntityState.Added | EntityState.Modified | EntityState.Deleted;
var entities = myEntityManager_em1.FindEntityGraph(roots, spans, entityState);
myEntityManager.SaveChanges(entities);
VB
' Get the root(s).
Dim roots = listOfEmployeesToSave

' Get the span(s).
Dim spans = New List(Of EntitySpan) From {New EntitySpan(GetType(Employee), _
  EntityRelations.FK_OrderSummary_Employee, EntityRelations.FK_Order_Details_Orders, _
    EntityRelations.FK_Order_Details_Products)}

' Find the related entities.
Dim entityState = entityState.Added Or entityState.Modified Or entityState.Deleted
Dim entities = myEntityManager_em1.FindEntityGraph(roots, spans, entityState)
myEntityManager.SaveChanges(entities)

But the roots do not all have to be of the same type.  For example:

C#
// Add root(s).
var roots = new List<Entity> { emp, supplier };

// Add span(s).
var spans = new List<EntitySpan> {
 new EntitySpan(typeof(Employee), EntityRelations.FK_OrderSummary_Employee, EntityRelations.FK_Order_Details_Orders),
 new EntitySpan(typeof(Supplier), EntityRelations.FK_Products_Suppliers, EntityRelations.FK_Products_Categories)
};

// Find the related entities.
var entityState = EntityState.Added | EntityState.Modified | EntityState.Deleted;
var entities = myEntityManager_em1.FindEntityGraph(roots, spans, entityState);
myEntityManager.SaveChanges(entities);
VB
' Add root(s).
Dim roots = New List(Of Entity) From {emp, Supplier}

' Add span(s).
Dim spans = New List(Of EntitySpan) From {New EntitySpan(GetType(Employee), _
  EntityRelations.FK_OrderSummary_Employee, EntityRelations.FK_Order_Details_Orders), _
   New EntitySpan(GetType(Supplier), EntityRelations.FK_Products_Suppliers, _
      EntityRelations.FK_Products_Categories)}

' Find the related entities.
Dim entityState = entityState.Added Or entityState.Modified Or entityState.Deleted
Dim entities = myEntityManager_em1.FindEntityGraph(roots, spans, entityState)
myEntityManager.SaveChanges(entities)
Tags: Save
Created by DevForce on February 19, 2011 18:30

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