Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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)

like image 208
Andreas Zita Avatar asked Oct 12 '10 19:10

Andreas Zita


People also ask

How do I save changes in Entity Framework?

Entity Framework Core Save Changes to the database using the SaveChanges method of DbContext. When we use the SaveChanges it prepares the corresponding insert , update , delete queries. It then wraps them in a Transaction and sends them to the database. If any of the queries fails all the statements are rolled back.

How do I update Entity Framework records?

We can update records either in connected or disconnected scenarios. In the connected Scenario, we open the context, query for the entity, edit it, and call the SaveChanges method. In the Disconnected scenario, we already have the entity with use. Hence all we need to is to attach/add it to the context.


1 Answers

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.

like image 186
Morteza Manavi Avatar answered Oct 05 '22 21:10

Morteza Manavi