Gopal SA
Gopal SA

Reputation: 959

EF6 Change tracking

I was implementing audit in my EF 6 database by adding a ModifiedDate property in the entity base and tried to override SaveChanges() by adding the below code (Taken from https://stackoverflow.com/a/6282472/82152)

 public class Session : ISession
    {
        public DbContext _context;

        public Session(DbContext context)
        {
            _context = context;
        }

. . .

        public int SaveChanges()
        {
            var context = ((IObjectContextAdapter)_context).ObjectContext;         

            var objectStateEntries =
                from e in context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified)
                where
                    e.IsRelationship == false &&
                    e.Entity != null &&
                    typeof(ModelBase).IsAssignableFrom(e.Entity.GetType())
                select e;

            foreach (var entry in objectStateEntries)
            {
                var modelBase = entry.Entity as ModelBase;
                modelBase.LastModifiedDate = DateTime.Now;
            }

            return _context.SaveChanges();
        }

After I changed one of the entity properties, and called SaveChanges - I could see that none of the objectStateEntries were marked as EntityState.Modified. It was all marked as EntityState.Unchanged.

Now after doing some reading, I changed my SaveChanges method to do context.DetectChanges(); after the first line - and it all worked. I tested a case where the entity property changed and another case where the entity property did not change, and it worked perfectly.

Now my concern is

  1. Although my current solution works, would it take a performance hit ?
  2. Why doesn't context.Configuration.AutoDetectChangesEnabled=true do the job of tracking the change automatically from property changes ?

Upvotes: 0

Views: 1035

Answers (1)

Erik Funkenbusch
Erik Funkenbusch

Reputation: 93494

You're not overriding SaveChanges(). You're creating a new wrapper class, and creating a SaveChanges method, and then trying to call SaveChanges() of your wrapped context. That's something totally different from overriding SaveChanges(). If you read the documentation for AutoDetectChangesEnabled You will find that it says this:

Gets or sets a value indicating whether the DetectChanges() method is called automatically by methods of DbContext and related classes. The default value is true.

So what it means is that DetectChanges() gets called when you call methods of the DbContext, which is something you are not doing. You ARE calling a method of the ObjectContext, which is not part of the DbContext (DbContext inherits from it), thus calling this method wouldn't trigger a DetectChanges() call.

Upvotes: 2

Related Questions