0

I have an Entity Framework code-first model where each entity implements the following interface:

public interface IEntity
{
    long Id { get; set; }
    DateTime DateTimeCreated { get; set; }
    DateTime DateTimeModified { get; set; }
}

In the DbContext, I have overridden the SaveChanges method that does the following:

public override int SaveChanges ()
{
    PropertyInfo property = null;
    var interfaceName = typeof(IEntity<>).Name;

    this.ChangeTracker.DetectChanges();

    foreach (var entry in this.ChangeTracker.Entries())
    {
        var now = DateTime.Now;
        var type = entry.Entity.GetType();
        var @interface = type.GetInterface(interfaceName, false);

        if (@interface != null)
        {
            if (entry.State == EntityState.Added)
            {
                property = type.GetProperty("DateTimeCreated");
                property.SetValue(entry.Entity, now);
                property = type.GetProperty("DateTimeModified");
                property.SetValue(entry.Entity, now);
            }
            else if (entry.State == EntityState.Modified)
            {
                // The property [DateTimeCreated] gets reset to default(DateTime).
                property = type.GetProperty("DateTimeModified");
                property.SetValue(entry.Entity, now);
            }
        }
    }

    return (base.SaveChanges());
}

The problem lies with the condition else if (entry.State == EntityState.Modified).

The presentation layer uses ViewModel DTOs and there is heavy use of custom code generation in the solution. As a result, using tools like AutoMapper and propagating the IEntity interface values to and from the DTO is not ideal.

When an entity is updated, and since the DTO knows nothing about the above properties, the IEntity instance has its DateTimeCreated property set to default(DateTime).

The IEntity interface is designed to shield developers/consumers from having to write plumbing code and since we don't propagate the DTOs, the only other option seems to be to make another round-trip to the database to fetch the DateTimeCreated value and then call base.SaveChanges.

Is there a work-around to avoid this round-trip that I may be missing?

Raheel Khan
  • 13,775
  • 12
  • 73
  • 160
  • 3
    What about this? http://stackoverflow.com/questions/12661881/exclude-property-on-update-in-entity-framework – kiziu Oct 06 '16 at 08:30
  • @kiziu: I did not know you could instruct EF to exclude selective columns. Worked like a charm. Thanks! – Raheel Khan Oct 06 '16 at 08:54

0 Answers0