patterncsharpMinor
Logging Entity Framework Changes - improve performance
Viewed 0 times
loggingimprovechangesperformanceframeworkentity
Problem
I have the following code to log changes using Entity Framework 6.
At the moment it only logs changes to a particular table - but I intend to expand it to cope with any table. I'm not sure of the best way to extract the table name.
I call this code before
At the moment it only logs changes to a particular table - but I intend to expand it to cope with any table. I'm not sure of the best way to extract the table name.
I call this code before
Db.SaveChanges. Db is the DBContext.private void LogHistory()
{
var entries = this.Db.ChangeTracker.Entries()
.Where(e => e.State == EntityState.Added || e.State == EntityState.Modified || e.State == EntityState.Deleted)
.ToList();
foreach (var entry in entries)
{
foreach (string o in entry.CurrentValues.PropertyNames)
{
var property = entry.Property(o);
var currentVal = property.CurrentValue == null ? "" : property.CurrentValue.ToString();
var originalVal = property.OriginalValue == null ? "" : property.OriginalValue.ToString();
if (currentVal != originalVal)
{
if (entry.Entity.GetType().Name.Contains("PropetyPair"))
{
// make and add log record
}
}
}
}
}Solution
Not a big deal, but this:
Can be shortened to this:
I'm not sure of the best way to extract the table name.
You're not doing that. You're looking at the name of the type of the entity - being an object/relational mapper, EF maps that entity to a table; if you need the table name then you need to look at the entity's table mappings.
I intend to expand it to cope with any table
How about having an
In terms of performance, you're looping too much:
This condition doesn't need
var currentVal = property.CurrentValue == null ? "" : property.CurrentValue.ToString();
var originalVal = property.OriginalValue == null ? "" : property.OriginalValue.ToString();Can be shortened to this:
var currentVal = (property.CurrentValue ?? string.Empty).ToString();
var originalVal = (property.OriginalValue ?? string.Empty).ToString();I'm not sure of the best way to extract the table name.
You're not doing that. You're looking at the name of the type of the entity - being an object/relational mapper, EF maps that entity to a table; if you need the table name then you need to look at the entity's table mappings.
I intend to expand it to cope with any table
How about having an
IEnumerable where you have all the entity types you want to log changes for, and then instead of getting the type's name and comparing with some magic string, you can just do _monitoredTypes.Contains(typeof(entry.Entity)) (not tested, just a thought).In terms of performance, you're looping too much:
if (entry.Entity.GetType().Name.Contains("PropetyPair"))This condition doesn't need
string o, as it's working off entry - thus, you can move that condition up two levels and only enter the 2nd loop when the entity type is interesting.Code Snippets
var currentVal = property.CurrentValue == null ? "" : property.CurrentValue.ToString();
var originalVal = property.OriginalValue == null ? "" : property.OriginalValue.ToString();var currentVal = (property.CurrentValue ?? string.Empty).ToString();
var originalVal = (property.OriginalValue ?? string.Empty).ToString();if (entry.Entity.GetType().Name.Contains("PropetyPair"))Context
StackExchange Code Review Q#39430, answer score: 7
Revisions (0)
No revisions yet.