We have been developing ‘Daylight‘, a records management system for the Freedom from Torture charity organisation dedicated to the treatment and rehabilitation of survivors of torture. Due to the sensitive nature of the data being recorded, Freedom from Torture wanted a way of tracking every change that was made to records.

The ‘Daylight’ application uses Entity Framework as an ORM layer over an SQL database. One option would have been to use database triggers to log changes. However, we wanted to track changes not in terms of the database model, but in terms of the application model. This would allow us to then easily query the log at a later point using the same application model and make sense of it. We could directly re-hydrate the logs back into C# objects in different recorded states in a strongly typed manner.

The way to track changes in terms of the application model, then, is to override the database context object’s SaveChanges method. However, inside that solution is quite a lot of complexity! I have spent some time over the last few weeks extracting the logging code from the client application, and the result of this is FrameLog, an open source logging library for Entity Framework.

It is compatible with EF version 5, and will work with both code-first and database-first approaches. The library in both binary and source forms can be used and modified for both commercial and non-commercial works (see the licence).

Links for FrameLog:

One of the features of FrameLog is the HistoryExplorer class, which allows type-safe querying of the logs. Here is an example:

public class Person
    public string Name { get; set; }

using (var db = new DatabaseContext())
    var explorer = new HistoryExplorer(db.FrameContext);
    var changes = explorer.ChangesTo(person, p => p.Name);
    foreach (var c in changes)
        Console.WriteLine("On {0}, name was changed to {1} by {2}", c.Timestamp, c.Value, c.Author");

Note that this example elides some User class that is used for recording who made the changes. Also note that you won’t just be able to drop in a FrameLog binary and do the above procedure—there is a little work to be done setting up the database’s “FrameContext”. See the documentation.

Martin Eden.


LShift is not the only place where FrameLog has been successfully put to use. Other users include:

  • StackOverflow user ‘Boggin’ who said: ‘I’ve implemented FrameLog in my project and it’s working fine with only a few hours work doing the integration. I’m using it now for a single table in my database that I needed to create an audit log for.’
  • StackOverflow user ‘fabriciorissetto’ who commented on this StackOverflow answer: ‘It’s a real nice framework. Very easy to use and customize. In less than 3 hours we have implemented this on our project. Thank you. You did a good job Martin =)’
  • Andrew Murray has raised a couple of tickets. On this StackOverflow answer he said ‘I can vouch for Framelog. Using it in my current project and it does what it says on the tin.’