Asp.net mvc 4 实体框架5变更日志如何实现?
我正在使用MVC4和entity framework 5创建一个应用程序。我如何实现这一点? 我环顾四周,发现我需要覆盖SaveChanges 有人对此有任何示例代码吗?我使用代码优先的方法 例如,我保存数据的方式如下:Asp.net mvc 4 实体框架5变更日志如何实现?,asp.net-mvc-4,entity-framework-5,Asp.net Mvc 4,Entity Framework 5,我正在使用MVC4和entity framework 5创建一个应用程序。我如何实现这一点? 我环顾四周,发现我需要覆盖SaveChanges 有人对此有任何示例代码吗?我使用代码优先的方法 例如,我保存数据的方式如下: public class AuditZoneRepository : IAuditZoneRepository { private AISDbContext context = new AISDbContext(); public
public class AuditZoneRepository : IAuditZoneRepository
{
private AISDbContext context = new AISDbContext();
public int Save(AuditZone model, ModelStateDictionary modelState)
{
if (model.Id == 0)
{
context.AuditZones.Add(model);
}
else
{
var recordToUpdate = context.AuditZones.FirstOrDefault(x => x.Id == model.Id);
if (recordToUpdate != null)
{
recordToUpdate.Description = model.Description;
recordToUpdate.Valid = model.Valid;
recordToUpdate.ModifiedDate = DateTime.Now;
}
}
try
{
context.SaveChanges();
return 1;
}
catch (Exception ex)
{
modelState.AddModelError("", "Database error has occured. Please try again later");
return -1;
}
}
}
无需覆盖SaveChanges 你可以 触发器
Context.ChangeTracker.DetectChanges()代码>//可能是必需的,具体取决于您的代理方法
然后在保存之前分析上下文。
然后你可以。。。将更改日志添加到当前工作单元。
因此,日志保存在一个提交事务中。
或者按照您认为合适的方式进行处理。
但同时保存更改日志。确保它是一个事务
分析上下文示例:
我有一个简单的工具,可以将上下文内容转储到调试输出,以便在调试器中时可以使用即时窗口检查内容。如
您可以将其用作准备更改日志的启动程序。
在调试器即时窗口中尝试。我的上下文类已完全转储
即时窗口调用示例<代码>UoW.Context.FullDump()代码>
public void FullDump()
{
Debug.WriteLine("=====Begin of Context Dump=======");
var dbsetList = this.ChangeTracker.Entries();
foreach (var dbEntityEntry in dbsetList)
{
Debug.WriteLine(dbEntityEntry.Entity.GetType().Name + " => " + dbEntityEntry.State);
switch (dbEntityEntry.State)
{
case EntityState.Detached:
case EntityState.Unchanged:
case EntityState.Added:
case EntityState.Modified:
WriteCurrentValues(dbEntityEntry);
break;
case EntityState.Deleted:
WriteOriginalValues(dbEntityEntry);
break;
default:
throw new ArgumentOutOfRangeException();
}
Debug.WriteLine("==========End of Entity======");
}
Debug.WriteLine("==========End of Context======");
}
private static void WriteCurrentValues(DbEntityEntry dbEntityEntry)
{
foreach (var cv in dbEntityEntry.CurrentValues.PropertyNames)
{
Debug.WriteLine(cv + "=" + dbEntityEntry.CurrentValues[cv]);
}
}
private static void WriteOriginalValues(DbEntityEntry dbEntityEntry)
{
foreach (var cv in dbEntityEntry.OriginalValues.PropertyNames)
{
Debug.WriteLine(cv + "=" + dbEntityEntry.OriginalValues[cv]);
}
}
}
编辑:获取更改
我用这个程序来获取技术
public class ObjectPair {
public string Key { get; set; }
public object Original { get; set; }
public object Current { get; set; }
}
public virtual IList<ObjectPair> GetChanges(object poco) {
var changes = new List<ObjectPair>();
var thePoco = (TPoco) poco;
foreach (var propName in Entry(thePoco).CurrentValues.PropertyNames) {
var curr = Entry(thePoco).CurrentValues[propName];
var orig = Entry(thePoco).OriginalValues[propName];
if (curr != null && orig != null) {
if (curr.Equals(orig)) {
continue;
}
}
if (curr == null && orig == null) {
continue;
}
var aChangePair = new ObjectPair {Key = propName, Current = curr, Original = orig};
changes.Add(aChangePair);
}
return changes;
}
我反编译了EF6。Get modified确实在使用私有位数组来跟踪具有
已经改变了
// EF decompiled source..... _modifiedFields is a bitarray
public override IEnumerable<string> GetModifiedProperties()
{
this.ValidateState();
if (EntityState.Modified == this.State && this._modifiedFields != null)
{
for (int i = 0; i < this._modifiedFields.Length; ++i)
{
if (this._modifiedFields[i])
yield return this.GetCLayerName(i, this._cacheTypeMetadata);
}
}
}
//EF反编译源…..\u modifiedFields是位数组
公共重写IEnumerable GetModifiedProperties()
{
这个;
if(EntityState.Modified==this.State&&this.\u modifiedFields!=null)
{
对于(int i=0;i
Phil-这是一个很好的示例。谢谢。我已经更新了上面的代码,我没有使用工作单元。所以你是说在我保存之前,我应该使用更改跟踪器来比较这两组值?如果我有不同的存储库,我是否需要复制代码?有许多存储库是可以的。代码是针对上下文的,所以我可以考虑上下文。考虑工作单位的方法,在其中控制保存,是控制更改日志的地方。UOW模式的存在是为了避免在存储库中保存500种方法;- PHIL -有一种简单的方法来只识别修改后的值吗?在记录中,我可能只改变1字段。current value函数只显示一个已修改的项,还是显示该记录的所有字段?Phil-这听起来可能很傻,但当EF将要更新的数据传递到基础表时,它肯定只向已更改的值发送update语句是吗?即在10个字段的行中,如果只更新了1个字段,则t发送到表中的sql应仅用于更新1个字段?如果是这种情况,那么ChangeTracker是否只会给我更改的数据?因为我只想记录这些…正确的EF更新集。让我看看是否可以快速访问
// EF decompiled source..... _modifiedFields is a bitarray
public override IEnumerable<string> GetModifiedProperties()
{
this.ValidateState();
if (EntityState.Modified == this.State && this._modifiedFields != null)
{
for (int i = 0; i < this._modifiedFields.Length; ++i)
{
if (this._modifiedFields[i])
yield return this.GetCLayerName(i, this._cacheTypeMetadata);
}
}
}