Entity Framework FAQ: Customizing Objects

 
[[articles:Entity Framework FAQ|Back to EF FAQs Table of Contents]] 

How do I write custom logic behind a "getter" or "setter"?

There are a few options available to you:

The Entity Data Model tools generate partial methods in the scalar property set accessors for each entity type. The OnPropertyNameChanging partial method is called before the value is set. The OnPropertyNameChanged partial method is called after the value is set. Implement these partial methods to add business logic. Note that there no partial methods for the getters, only for the setters.

You can also subscribe to the following events: EntityObject.PropertyChanging and EntityObject.PropertyChanged. For more information, see How to: Execute Business Logic During Scalar Property Changes.

Another option is to use custom data classes with your data model. Starting with EF 4 you can use POCO to create your custom classes. For more information, see Working with POCO Entities. In EF 3.5 SP1 you could either derive your classes from EntityObject, or implement interfaces on your custom data class.

Starting with EF 4 you could also consider modifying the T4 template files from which the object-layer code is generated. For more information, see How to: Customize Object-Layer Code Generation.

From http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=573966&SiteID=1.

Is it possible to write logic that distinguishes between user code calls to the data class and framework materialization of the class?

In EF 4 the ObjectContext.ObjectMaterialized event is raised when a new entity is created from data in the data source as part of a query or load operation. The event occurs after all scalar, complex, and reference properties have been set on an object, but before collections are loaded. If an object with the same key value exists in the object context, the Entity Framework will not re-create the object and this event will not be raised. ObjectContext.Attach and AddObject will not cause this event to be fired.

In EF 3.5 SP1 there isn't a system in place to allow you to easily distinguish between cases where the system is materializing an entity and user code is calling a constructor or setter.

From http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=2301046&SiteID=1.

How do I execute custom code on a SaveChanges call?

ObjectContext has a SavingChanges event that is fired whenever SaveChanges is called on the context before any changes are persisted to the database. There is also an OnContextCreated partial method that is called from the context constructor and can be used to subscribe a handler to that event. This event handler can be used to enforce business logic that involves multiple entities.

Starting with EF 4 the SaveChanges method is virtual. This means that you can override this method directly instead of subscribing to the SavingChanges event. The How to: Execute Business Logic When Saving Changes (Entity Framework) topic shows different ways to add the business logic when saving changes.

How do I write business logic that validates interactions between multiple properties on an entity?

The Entity Framework allows creating a Validate method that can be overridden for every concrete type in the system. Here is how to do it:

  1. Create an abstract type in your model from which all of your concrete types inherit or an interface that all of your entities will implement on their partial class. Add to the abstract class or interface a Validate method that can be overridden in the various concrete classes as appropriate.
  2. Create an event handler for the SavingChanges event on the object context that goes through all of the inserted or updated entities (found by examining the ObjectStateManager) and calls the Validate method. For example:
foreach (ObjectStateEntry entry in
     ((ObjectContext)sender).ObjectStateManager.GetObjectStateEntries( 
     EntityState.Added | EntityState.Modified)) 
 { 
     IValidator obj = entry.Entity as IValidator; 
     bool valid = true; 
     if (obj != null) 
         valid = obj.Validate(); 
         // If the validation method returns a problem string, raise an error. 
         if (valid != true) 
         { 
             throw new ArgumentException(...); 
         } 
     } 
 }

For more information, see How to: Execute Business Logic When Saving Changes.

You can also validate property values in the setters. Note, however, that the Entity Framework executes property setters of an object during materialization. If the data loaded from the database does not validate, that would obviously cause issues. If the validation logic is expensive to execute then there could be performance implications too.

From http://forums.microsoft.com/MSDN/ShowPost.aspx?PostID=573966&SiteID=1.
 
[[articles:Entity Framework FAQ|Back to EF FAQs Table of Contents]]