5
\$\begingroup\$

The entity framework will only save properties it detects has changed via its proxy classes. I have a situation where I want a property to always be saved no matter if it changed or not.

I wrote a blank attribute called AlwaysUpdate which I apply to the property. I then overrode SaveChanges to scan for these attributes and mark the field as Modified. Is this code all right?

public override int SaveChanges()
{
 var changeSet = ChangeTracker.Entries();
 if (changeSet != null)
 {
 foreach (var entry in changeSet.Where( c=> c.State == System.Data.EntityState.Modified ))
 {
 foreach (var prop in entry.Entity.GetType().GetProperties().Where(p => p.GetCustomAttributes(typeof(AlwaysUpdateAttribute), true).Count() > 0).Select( p => p.Name ))
 {
 if (entry.State == System.Data.EntityState.Added || entry.State == System.Data.EntityState.Unchanged) continue;
 // Try catch removes the errors for detached and unchanged items
 try
 {
 entry.Property(prop).IsModified = true;
 }
 catch { }
 }
 }
 }
 return base.SaveChanges();
}
Heslacher
50.9k5 gold badges83 silver badges177 bronze badges
asked Jan 19, 2013 at 19:45
\$\endgroup\$

1 Answer 1

3
\$\begingroup\$
  • Instead of checking .Count() > 0 which needs to iterate over the IEnumerable you can just use .Any() which only checks if at least one item is contained in the IEnumerable

  • you should extract the result of typeof(AlwaysUpdateAttribute) to a variable.

    Type desiredType = typeof(AlwaysUpdateAttribute);
    
  • you can restrict the outer loop by adding the "continue condition" to the Where() method. For readability we will do this outside of the loop

    changeSet = changeSet.Where( c=> 
     c.State == System.Data.EntityState.Modified 
     && !(entry.State == System.Data.EntityState.Added 
     || entry.State == System.Data.EntityState.Unchanged) 
     ); 
    
  • you shouldn't shorten any variable names -> prop should be propertyName

Refactoring

Implementing all above will lead to

public override int SaveChanges()
{
 var changeSet = ChangeTracker.Entries();
 if (changeSet != null)
 {
 changeSet = changeSet.Where( c=> 
 c.State == System.Data.EntityState.Modified 
 && !(entry.State == System.Data.EntityState.Added 
 || entry.State == System.Data.EntityState.Unchanged) 
 ); 
 Type desiredType = typeof(AlwaysUpdateAttribute);
 foreach (var entry in changeSet)
 {
 foreach (var propertyName in entry.Entity.GetType().GetProperties().Where(p => p.GetCustomAttributes(desiredType , true).Any()).Select( p => p.Name ))
 {
 // Try catch removes the errors for detached and unchanged items
 try
 {
 entry.Property(propertyName).IsModified = true;
 }
 catch { }
 }
 }
 }
 return base.SaveChanges();
}
 foreach (var entry in changeSet) 
 {
 foreach (var prop in entry.Entity.GetType().GetProperties().Where(p => p.GetCustomAttributes(desiredType , true).Any()).Select( p => p.Name ))
 {
 // Try catch removes the errors for detached and unchanged items
 try
 {
 entry.Property(prop).IsModified = true;
 }
 catch { }
 }
answered Dec 18, 2014 at 14:22
\$\endgroup\$

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.