Databases Reference
In-Depth Information
public override int SaveChanges(SaveOptions options)
{
IEnumerable<ObjectStateEntry> stateEntries = this.ObjectStateManager
.GetObjectStateEntries(ChangedEntityStates)
.Where(stateEntry => !stateEntry.IsRelationship);
foreach (ObjectStateEntry stateEntry in stateEntries)
this.BeforeSaveChanges(stateEntry);
return base.SaveChanges(options);
}
When the
SaveChanges
method is called, you could have multiple entities that were
added, modified, and deleted. The modifications are stored in the
ObjectContext
but not
saved in the database yet. The
BeforeSaveChanges
method ensures that each of these
changes is valid according to the business rules defined by the entity type. Authorization,
being a specialized form of business rules, fits this pattern as well and you can extend the
code to perform it. Here is a new version of this method with the changes highlighted in
bold font:
private void BeforeSaveChanges(ObjectStateEntry stateEntry)
{
Authorize(stateEntry.Entity.GetType(),
EntityStateToAction(stateEntry.State));
var savable = stateEntry.Entity as ISavableObject;
if (savable != null)
savable.BeforeSave(stateEntry);
if (stateEntry.State != EntityState.Deleted)
this.Validate(stateEntry);
}
For each added, modified, or deleted entity, the
BeforeSaveChanges
method now calls the
Authorize
method, passing it the type of the entity and the action performed. Notice that
the
State
property of the
ObjectStateEntry
defines the action performed on an entity as
a value of the built-in enum type
EntityState
; however, the
AuthorizationAttribute
relies on the custom
Actions
enum type instead. To translate between the two types, you
need a simple function,
EntityStateToAction
, shown here:
private static Actions EntityStateToAction(EntityState state)
{
switch(state)
{
case EntityState.Added: return Actions.Insert;
case EntityState.Modified: return Actions.Update;
case EntityState.Deleted: return Actions.Delete;