How to auto-update the Modified property on a Entity in Entity Framework 4 when saving?

Andreas Zita picture Andreas Zita · Oct 12, 2010 · Viewed 8.6k times · Source

Im using EF4 in VS2010, POCO's and the model-first approach.

My entity has the following properties: Id:Guid, Name:String, Created:DateTime, Modified:DateTime, Revision:Int32.

I create my entity, set the name and save it to the database using the EF4-context. This should set Id to a new Guid (works with Identity-SGP), Created set to now, Modified left as null, Revision set to 0. I retrieve the entity, change the name and save it again. This time the Modified-value should be set to now and revision should be 1.

How do I best accomplish this using EF4 with the EDMX-designer?

Update:

This was what I ended up using:

public override int SaveChanges(System.Data.Objects.SaveOptions options)
{
    foreach (ObjectStateEntry entry in ObjectStateManager.GetObjectStateEntries(EntityState.Added | EntityState.Modified).Where(e => e.Entity is EntityBase))
    {
        EntityBase entity = entry.Entity as EntityBase;
        if (entry.State == EntityState.Added)
        {
            entity.Version = new Version() { Major = 1, Minor = 0, Revision = 0 };
            entity.Created = DateTime.Now;
            if (OperationContext.Current != null) entity.CreatedBy = OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name;
        }
        else if (entry.State == EntityState.Modified)
        {
            entity.Version.Revision++;
            entity.Modified = DateTime.Now;
            if (OperationContext.Current != null) entity.ModifiedBy = OperationContext.Current.ServiceSecurityContext.WindowsIdentity.Name;
        }
    }

    return base.SaveChanges(options);
}

Which isnt working... :(

The problem is that the entry.State is still unmodified even if I explicitly run the MarkAsModified()-method. I dont get this...

Why isnt change-tracking enabled by default? Im using self-tracking entities so why would I want it off and explicitly turn it on everytime? And why is entities persisted to db even if state is unmodified? And whats the difference between EntityState and ObjectState? At the moment Im making all changes and updates serverside but I will also use a WCF-service to transfer entities back and forth some time later... Is there a difference in how changes are treated here? If serverside all changes, no matter changetracking on/off, is persisted?? What I want is that nothing should ever be able to be stored without also updating Modified, Revision etc. These properties should always be set on the server when the object is received back and has changed. (Im not talking sql-server-side here but service-server-side)

Answer

Morteza Manavi picture Morteza Manavi · Oct 12, 2010

Let's assume your Entity Type name is Product:

partial void OnContextCreated() {
    this.SavingChanges += Context_SavingChanges;
}

void Context_SavingChanges(object sender, EventArgs e) {

    IEnumerable objectStateEntries =
            from ose
            in this.ObjectStateManager.GetObjectStateEntries(EntityState.Added | 
                                                            EntityState.Modified)
            where ose.Entity is Product
            select ose;

    Product product = objectStateEntries.Single().Entity as Product;

    product.ModifiedDate = DateTime.Now;
    product.ComplexProperty.Revision++;
}


If you are looking to use this code for populating common field such as ModifiedDate or ModifiedBy for all of your entities then please take a look at this post:
Entity Framework - Auditing Activity

By the way, StoreGeneratedPattern and ConcurrencyMode has nothing to do with this, they are there for completely different and unrelated stuff.