c# entity-framework entity-framework-6 audit audit-trail

c# - Entidad Marco 6: auditoría/seguimiento de cambios



entity-framework entity-framework-6 (3)

Hay un paquete nuget para esto https://www.nuget.org/packages/TrackerEnabledDbContext

Fuente: https://github.com/bilal-fazlani/tracker-enabled-dbcontext

Tengo mi proyecto principal en C #.

Trabajo en una base de datos, donde algunas tablas tienen las columnas "user_mod" y "date_mod" para firmar quién y cuándo hicieron algunas modificaciones y lo mismo con "data_new" y "user_new".

Mi pregunta: ¿hay alguna forma de centralizar esto y hacer que estos datos se inserten automáticamente, donde creo la instancia de dbContext ?

Si no, usaré una herramienta de seguimiento de auditoría. He visto algunos de estos, pero hay un problema: todos estos requieren algún código en mi modelo. Pero no quiero escribir en mi modelo, porque si tengo que cambiarlo, perderé los mods. ¿Es posible utilizar un seguimiento de auditoría para EF6 sin escribir en los archivos del modelo? ¿Cómo?

EDITAR:

Mi intento de anular los saveChanges.

public partial class PieEntities : DbContext { public override int SaveChanges(System.Data.Objects.SaveOptions options) { var timestamp = DateTime.Now; EntityState es = EntityState.Added; ObjectStateManager o = new ObjectStateManager(); foreach (ObjectStateEntry entry in o.GetObjectStateEntries(EntityState.Added )) { if (entry.Entity.GetType() == typeof(TabImpianti)) { TabImpianti impianto = entry.Entity as TabImpianti; impianto.DATA_INS = timestamp; impianto.DATA_MOD = timestamp; string u = mdlImpostazioni.p.UserName; impianto.USER_INS = u; impianto.USER_MOD = u; } } return base.SaveChanges(options); } }

ACTUALIZACIÓN: resumí la solución aquí .


Hay una forma de hacerlo: puede crear una clase parcial que tenga el mismo nombre que el contexto de su objeto e implementar una anulación del método SaveChanges . En esta anulación, puede ver todos los cambios que se enviarán al DB y procesarlos.

Puede procesarlos como desee, en el siguiente ejemplo creé una interfaz IAutoTimestampEntity que contenía una fecha de creación y una fecha de modificación. Cualquier objeto de este tipo se actualizará automáticamente con la hora del cambio.

public override int SaveChanges(System.Data.Objects.SaveOptions options) { var timestamp = DateTime.Now; foreach (var InsertedAutoTimestampEntity in ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added).Select(ose => ose.Entity).OfType<IAutoTimestampEntity>()) { InsertedAutoTimestampEntity.CreationDate = timestamp; InsertedAutoTimestampEntity.ModificationDate = timestamp; } foreach (var UpdatedAutoTimestampEntity in ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Modified).Select(ose => ose.Entity).OfType<IAutoTimestampEntity>()) { UpdatedAutoTimestampEntity.ModificationDate = timestamp; } return base.SaveChanges(options); }

Puede usar el mismo principio, o puede ver el tipo de cada entidad modificada en detalles. Aunque me gusta el aspecto declarativo de la interfaz. Le permite exponer un aspecto de la automatización de forma explícita en lugar de dejar que la capa de EF lo haga en silencio.

Si tiene un DbContext lugar de un ObjectContext , DbContext su DbContext a IObjectContextAdapter para acceder al ObjectStateManager


Si usa el DbContext de DbContext , puede usar ChangeTracker en la anulación de SaveChanges para buscar entidades adicionales o modificadas de tipo personalizado, por ejemplo IAuditedEntity.

public interface IAuditedEntity { string CreatedBy { get; set; } DateTime CreatedAt { get; set; } string LastModifiedBy { get; set; } DateTime LastModifiedAt { get; set; } } public override int SaveChanges() { var addedAuditedEntities = ChangeTracker.Entries<IAuditedEntity>() .Where(p => p.State == EntityState.Added) .Select(p => p.Entity); var modifiedAuditedEntities = ChangeTracker.Entries<IAuditedEntity>() .Where(p => p.State == EntityState.Modified) .Select(p => p.Entity); var now = DateTime.UtcNow; foreach (var added in addedAuditedEntities) { added.CreatedAt = now; added.LastModifiedAt = now; } foreach (var modified in modifiedAuditedEntities) { modified.LastModifiedAt = now; } return base.SaveChanges(); }