Reputation: 51
I have looked through many examples of creating an audit trail using the Entity Framework and have yet to find anything that works for me. There must be a slick/terse way to do it by simply overriding SaveChanges in the DB Context and using the ChangeTracker...issues I have run into are things such as when adding (creating) an entity it does not have an ID until after you save it and when you save it, it seems to blast what's in the change tracker. Anyway, I have got an audit trail working but it's ugly as hell and I was looking for help in simplifying this and making it such that I don't have to add on to a horrible if-then every time I add an entity! Any and all help appreciated.
public bool CreateRecord(object o)
{
Audit audit = new Audit()
{
ChangeTypeID = (int)Audit.ChangeType.CREATE,
TimeStamp = GetCurrentDateTime(),
RecordClass = o.GetType().ToString(),
NewValue = "",
ReasonForChange = "Record Creation"
};
if (o.GetType() == typeof(Permission))
{
Permission x = (Permission)o;
audit.OriginalValue = x.ToString();
Permissions.Add(x);
SaveChanges();
audit.RecordID = x.ID;
}
else if (o.GetType() == typeof(User))
{
User x = (User)o;
audit.OriginalValue = x.ToString();
Users.Add(x);
SaveChanges();
audit.RecordID = x.ID;
}
else if (o.GetType() == typeof(LogIn))
{
LogIn x = (LogIn)o;
audit.OriginalValue = x.ToString();
LogIns.Add(x);
SaveChanges();
audit.RecordID = x.ID;
}
else if (o.GetType() == typeof(Marker))
{
Marker x = (Marker)o;
audit.OriginalValue = x.ToString();
Markers.Add(x);
SaveChanges();
audit.RecordID = x.ID;
}
else if (o.GetType() == typeof(Method))
{
Method x = (Method)o;
audit.OriginalValue = x.ToString();
Methods.Add(x);
SaveChanges();
audit.RecordID = x.ID;
}
else if (o.GetType() == typeof(Sample))
{
Sample x = (Sample)o;
audit.OriginalValue = x.ToString();
Samples.Add(x);
SaveChanges();
audit.RecordID = x.ID;
}
else if (o.GetType() == typeof(Run))
{
Run x = (Run)o;
audit.OriginalValue = x.ToString();
Runs.Add(x);
SaveChanges();
audit.RecordID = x.ID;
}
else if (o.GetType() == typeof(XYDataSet))
{
XYDataSet x = (XYDataSet)o;
audit.OriginalValue = x.ToString();
XYDataSets.Add(x);
SaveChanges();
audit.RecordID = x.ID;
}
else
{
return false;
}
// Save audit record
audit.UserID = ((App)Application.Current).GetCurrentUserID();
Audits.Add(audit);
SaveChanges();
return true;
}
Upvotes: 1
Views: 776
Reputation: 13146
I am assuming that all of the entities belongs to same project/assembly, so you can try something like that and notice that this code doesn't tested, modifications might be needed.
public bool CreateRecord(object o)
{
Audit audit = new Audit()
{
ChangeTypeID = (int)Audit.ChangeType.CREATE,
TimeStamp = GetCurrentDateTime(),
RecordClass = o.GetType().ToString(),
NewValue = "",
ReasonForChange = "Record Creation"
};
var entityType = Assembly.GetAssembly(typeof(Permission)).GetTypes().Where(x => x == o.GetType())
.FirstOrDefault(); // Determine the desired entity (assumed all of the entities belongs to same project/assembly)
if (entityType != null)
{
var convertedObject = Convert.ChangeType(o, entityType); // Convert object to entity
audit.OriginalValue = convertedObject.ToString();
var entity = yourContext.Set(entityType).Add(convertedObject); // Get DbSet for casted entity
SaveChanges();
audit.RecordID = x.ID;
}
else
{
return false;
}
// Save audit record
audit.UserID = ((App)Application.Current).GetCurrentUserID();
Audits.Add(audit);
SaveChanges();
return true;
}
Upvotes: 0