Auditing with Entity Framework

3

I want to do the audit tables for my entities. At first I thought about overwriting the SaveChanges method. I also thought about writing a method that will be doing the audit on my% base%. Using both ways, I will have a single auditing table for my entire system.

But for performance issues I need each entity to have its log table.

What would be the best way to intercept the type of my entity so I can save it in the audit table of it?

My code so far, looks like this:

public override int SaveChanges()
{
     var entriesAdicionadas = ChangeTracker.Entries().Where(e => e.State == EntityState.Added).ToList();

     var entriesModificadas = ChangeTracker.Entries().Where(e => e.State == EntityState.Modified).ToList();

     var entriesDeletadas = ChangeTracker.Entries().Where(e => e.State == EntityState.Deleted).ToList();
     foreach (var entry in entriesAdicionadas)
     {

     }
     int result = base.SaveChanges();

     foreach (var entry in entriesModificadas)
     {
         var nome = entry.Entity.GetType().Name;
     }

     base.SaveChanges();

     foreach (var entry in entriesDeletadas)
     {
         var nome = entry.Entity.GetType().Name;
     }

     return result;
} 
    
asked by anonymous 13.10.2014 / 18:22

1 answer

1

Home Deployment

First you need to create a way to relate the Model of Log to the Model that will be audited. This can be done by declaring a Model with generic. For example:

public class ModelDeLogGenerico<T>
    where T: class
{

}

T does not have to be class . T can be an ancestral class of all its Models , or else an interface. In some projects I do, all Models are derived from an interface called IEntityBase , where I force Model to have two more properties: in the first record the date where the record was created and on the second the date it was last modified, which is something like this:

namespace MyProject.Models.Interfaces
{
    interface IEntityBase
    {
        DateTime LastModified { get; set; }
        DateTime CreatedOn { get; set; }
    }
}

This ensures that your Model of Log can not necessarily receive any class. The class to be valid needs to implement IEntityBase . My Log class, therefore, would look like this:

public class ModelDeLogGenerico<T>
    where T: IEntityBase
{

}

Suppose now any Model of your system:

public class Fruta 
{
    ...
}

Your respective Log will be:

public class LogFruta<Fruta>
{
    ...
}

Having this, we can now identify that LogFruta audits Fruta . The following Reflection-based code looks in the Assembly of your application which class has as a generic argument the class Fruta :

var log = Assembly.GetExecutingAssembly().GetTypes().FirstOrDefault(t => t.GetGenericArguments()[0] == entry.GetType());

Ready Solutions

The EntityFramework.Extended has the native ability to log you on. Have an explanation here .

    
13.10.2014 / 21:07