entity framework6:审计/跟踪更改
我有我的核心项目在C#中。
我在一个数据库上工作,其中一些表格有“user_mod”和“date_mod”这两个字段,用于标记谁和什么时候做了一些mod,和“data_new”和“user_new”是一样的。
我的问题:是否有办法集中这一点,并使这个数据自动插入,我创builddbContext
的实例?
如果没有,我将使用审计跟踪工具。 我已经看到了其中一些,但是有一个问题:所有这些都需要我的模型中的一些代码。 但是我不想写我的模型,因为如果我必须改变它,我会丢失mods。 是否可以使用EF6的审计跟踪而不写入模型文件? 怎么样?
编辑:
我尝试重写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); } }
更新:我在这里总结了解决scheme 。
如果使用DbContext
的DbContext
,则可以使用SaveChanges
覆盖中的ChangeTracker
来查找自定义types的添加/修改实体,例如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(); }
有这个https://www.nuget.org/packages/TrackerEnabledDbContext的; nuget包
来源: https : //github.com/bilal-fazlani/tracker-enabled-dbcontext
有一种方法可以实现:您可以创build一个与对象上下文同名的分部类,并实现SaveChanges
方法的重写。 在这个覆盖中,您可以查看将推送到数据库并处理它们的所有更改。
您可以按照您喜欢的方式处理它们,在下面的示例中,我创build了一个包含创builddate和修改date的IAutoTimestampEntity
接口。 任何这种types的对象都会随着更改时间自动更新。
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); }
您可以使用相同的原则,也可以详细查看每个更改的实体的types。 我喜欢界面的声明性方面。 它可以让你明确地公开自动化的一个方面,而不是由EF层静静地完成。
如果您有一个DbContext
而不是ObjectContext
, DbContext
您的DbContext
为IObjectContextAdapter
以访问ObjectStateManager