Application-level change logging with EntityFramework

By: on April 22, 2013

We have been developing Daylight, which is a records management system for Freedom from Torture, a charity 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 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 allows us to then easily query the log at a later point using the same application model and make sense of it. We can directly re-hydrate the logs back into C# objects in different recorded states in a strongly typed manner.

The solution is to override the database context object’s SaveChanges method. However, inside that statement 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 is FrameLog, an open source logging library for Entity Framework.

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

Links for FrameLog:

One of the features of FrameLog is the HistoryExplorer class, that 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 – there is a little work to be done setting up the database’s “FrameContext”. See the documentation.



  1. Rob says:

    Any chance this might work with RF 4.1?

  2. Martin Eden says:

    I assume you meant EF 4.1? It think it actually should work fine with EF 4.1 – it’s just that in order to support EF 5 the library itself references EF 5. Please give it a try and let me know whether it works.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>