Thursday, January 17, 2013

Explicit Loading Entity Objects


There are two ways with which we could implement explicit load for entity objects.

1. Using Load() method
2. Using CreateSourceQuery() and Attach()


  • Load() Method


To load related entity objects of an object explicitly, we could use Load() method. When we call Load() method on an object to get its child object collection, ValidateLoad<TEntity> is called before loading the collection. If we use Load() method and if the collection is already loaded in the object context, it enforces one of the MergeOption specified.

MergeOptions are:

AppendOnly: Objects already present in ObjectContext are not loaded again from data source.
OverwriteChanges: Objects are always loaded overwritting the changes in the ObjectContext.
PreserveChanges: Objects are always loaded but changes in the ObjectContext are preserved.
NoTracking: Objects are maintained in detached state and are not tracked.

To know whether the object collection has already been loaded to ObjectContext or not, we could use IsLoaded() which returns true/false. But when we initiate a call to Load() method, IsLoaded() is not automatically checked.

Note: When we call Load() method in a loop, each object service tries to open a new data reader. This may fail if we have not set the "multipleactiveresultsets=true" in the connection string.Once we load the result to List<T>, the data reader connection is closed.

Example:


// Load the orders for the customer 
if (!customer.SalesOrderHeader.IsLoaded)
{
    customer.SalesOrderHeader.Load();
}



  • CreateSourceQuery() and Attach()

Using CreateSourceQuery(), we get new instance of ObjectQuery<T> that returns the same set of objects. This method is particularly useful when going for more complex joins, unions and filtering. It can be also used to return the same object in detached state by using the MergeOption, NoTracking. CreateSourceQuery() is used to filter objects in an EntityCollection<TEntity> to enable us to bind only those filtered objects. The result which we get using the CreateSourceQuery() is then attached to the object using Attach() method.


CreateSourceQuery() may result in an "InvalidOperationException" if the object is in Added state or when the object is in Detached state with a MergeOption other than NoTracking.

Entity States are:

Detached: Object exists but not tracked by Object Services. Operations that can make the entity object Detached are


  1. Entity object is created and not added to ObjectContext
  2. When object removed from ObjectContext by calling Detach
  3. When the object is loaded with MergeOption, NoTracking
Unchanged: Object has not been modified since it was loaded or since the last time the SaveChanges method was called.
Added:Object is been added to the ObjectContext, but the SaveChanges method is not called yet.
Deleted: Object is been deleted from ObjectContext using DeleteObject method.
Modified: Object is changed or modified, but SaveChanges method is not been called.



Example:


// Return the customer's first five orders with line items and
// attach them to the SalesOrderHeader collection.
customer.SalesOrderHeader.Attach(
  customer.SalesOrderHeader.CreateSourceQuery().Include("SalesOrderDetail").Take(5));



No comments:

Post a Comment