patterncsharpMinor
AlwaysUpdate attribute for Entity Framework Code First POCO
Viewed 0 times
alwaysupdatefirstforattributecodepocoframeworkentity
Problem
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
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();
}Solution
-
Instead of checking
-
you should extract the result of
-
you can restrict the outer loop by adding the "continue condition" to the
-
you shouldn't shorten any variable names ->
Refactoring
Implementing all above will lead to
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 propertyNameRefactoring
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 { }
}Code Snippets
Type desiredType = typeof(AlwaysUpdateAttribute);changeSet = changeSet.Where( c=>
c.State == System.Data.EntityState.Modified
&& !(entry.State == System.Data.EntityState.Added
|| entry.State == System.Data.EntityState.Unchanged)
);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 { }
}Context
StackExchange Code Review Q#20726, answer score: 3
Revisions (0)
No revisions yet.