我有一个处理xml文件输入的Windows服务。每次收到新文件时,我都需要插入新记录并更新现有记录。我现在需要在每次操作发生后实现insert \ update历史记录。我需要通过显示旧值和新值来将其保存在单独的表中。是否有任何现有的方法或技术可以更容易地实现这一点,例如比较两个对象和识别修改的字段。请提供任何建议。我正在使用Entityframework 5.0和sql 2012。
答案 0 :(得分:0)
有多种方法可以做到这一点。
使用持久性API框架的拦截器。例如,JPA或Hibernate框架提供围绕实体操作的外观,这些操作在数据库中的DML操作之后运行。
事件监听器:您应该能够在持久性框架内创建事件监听器,这些监听器将被触发,并在每次DML操作后在历史表中插入历史数据。
数据库触发器:这确实是维护给定行/表的历史信息的最简单方法之一。
希望这些指针有所帮助 了Anant
答案 1 :(得分:0)
专门针对EF,您可以覆盖DbContext.SaveChanges()
并迭代DbContext.ChangeTracker.Entries()
。每个条目都包含实体属性的当前值和原始值。
答案 2 :(得分:0)
我的实体类派生自ObjectContext
,但未提供ChangeTracker
来获取修改后的值。但是,对于ObjectContext
,我们可以使用DBContext.ObjectStateManager.GetObjectStateEntries(EntityState.Modified)
获取修改后的值
如果需要,您可以使用EntityState.Deleted
,EntityState.Added
。
以下是示例实施
Entities DBContext = new Entities();
var d = DBContext.StudentTableName.Where(x => x.stname == "Stock").FirstOrDefault();
if(d!= null)
{
d.Id = "345";
DBContext.StudentTableName.ApplyCurrentValues(d);
//Need to Include Audit Logging before save, or can override save function.
var entrList = DBContext.ObjectStateManager.GetObjectStateEntries(EntityState.Modified);
foreach (var stateEntry in entrList)
{
var currentValues = stateEntry.CurrentValues;
var originalValues = stateEntry.OriginalValues;
var modifiedProperties = stateEntry.GetModifiedProperties();
foreach (string modifiedProperty in modifiedProperties)
{
var currentValue = currentValues.GetValue(currentValues.GetOrdinal(modifiedProperty));
var originalValue = originalValues.GetValue(originalValues.GetOrdinal(modifiedProperty));
if (!originalValue.Equals(currentValue))
{
//Perform the logging operation
}
}
}
// Audit Logging Performed
DBContext.SaveChanges();
}