Tuesday, April 21, 2009

Executing custom business logic when saving (when using the ADO.NET Entity Framework)

ADO.NET Entity Framework allows you to use partial class implementations to extend the framework and entities to meet your needs. One thing you may need to do is add some custom business logic that is supposed to happen when an entity is saved. In this entry I will show one way to implement this.

The ObjectContext is responsible (among other things such as tracking changes) for saving changes from the entities in the ObjectContext to the database. This means that if we want to do something just before the save changes is called we need to do it in a proxy object or other wrapper like business object, or we can extend the ObjectContext. In this entry, I show how to extend the ObjectContext.

The ObjectContext has many events. One of them is the SavingChanges event. This is called just before the standard ObjectContext save changes code is executed. This means that if we wanted to set some default values such as DateCreated to the current date and time we can. All we have to do is find the object we want to modify, and set the property as desired.

One trick to using the partial class implementation of our ObjectContext object is that we can use the partial implementation of the OnContextCreated() method. This is called early on in the cycle and can be used for registering our handler for the SavingChanges event.

The code below shows an example of how this can be done.

public partial class MyEntities
{
 partial void OnContextCreated()
 {
  // Register the handler for the SavingChanges event.
  this.SavingChanges += new EventHandler(MyEntities_SavingChanges);
 }

 // fires before save is called by ObjectContext
 private void MyEntities_SavingChanges(object sender, EventArgs e)
 {
  foreach (ObjectStateEntry entry in ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added))
  {
   if (entry.Entity.GetType() == typeof(MyEntity))
   {
    MyEntity contract = entry.Entity as MyEntity;
    contract.DateCreated = DateTime.Now;
   }
  }
 }
}


For alternate ways of implementing this such as using a proxy, check out: http://msdn.microsoft.com/en-us/library/cc716714.aspx

For more info on customizing Entity Framework objects, check out:
http://msdn.microsoft.com/en-us/library/bb738612.aspx

For a good starting point and more information on this topic on the ADO.NET Entity Framework (EF), check out:
http://msdn.microsoft.com/en-us/library/bb399572.aspx
or  http://blogs.msdn.com/dsimmons/pages/entity-framework-faq.aspx or http://msdn.microsoft.com/en-us/data/aa937723.aspx

No comments: