C# 重写SaveChangesSync实体框架6以记录修改的属性值
我正在开发一个ASP.NET核心项目,其中在C# 重写SaveChangesSync实体框架6以记录修改的属性值,c#,asp.net-mvc,entity-framework,entity-framework-6,C#,Asp.net Mvc,Entity Framework,Entity Framework 6,我正在开发一个ASP.NET核心项目,其中在SaveChanges中,我需要记录更新的值 根据,我试图覆盖savechangesync,但出现以下错误: 无法将“MyProject.ApplicationDbContext”类型的对象强制转换为“System.Data.Entity.Infrastructure.IObjectContextAdapter”类型 代码: public override Task savechangessync(CancellationToken Cancellat
SaveChanges
中,我需要记录更新的值
根据,我试图覆盖savechangesync
,但出现以下错误:
无法将“MyProject.ApplicationDbContext”类型的对象强制转换为“System.Data.Entity.Infrastructure.IObjectContextAdapter”类型
代码:
public override Task savechangessync(CancellationToken CancellationToken=default)
{
ChangeTracker.DetectChanges();
ObjectContext ctx=((IObjectContextAdapter)this).ObjectContext;
列表objectStateEntryList=ctx.ObjectStateManager
.GetObjectStateEntries((System.Data.Entity.EntityState)(EntityState.Added | EntityState.Modified | EntityState.Deleted))
.ToList();
foreach(objectStateEntryList中的ObjectStateEntry条目)
{
如果(!entry.IsRelationship)
{
开关(进入状态)
{
案例(System.Data.Entity.EntityState)EntityState.Add:
//写日志。。。
打破
案例(System.Data.Entity.EntityState)EntityState.Deleted:
//写日志。。。
打破
案例(System.Data.Entity.EntityState)EntityState.Modified:
foreach(entry.GetModifiedProperties()中的字符串propertyName)
{
DbDataRecord original=entry.OriginalValues;
字符串oldValue=original.GetValue(original.GetOrdinal(propertyName)).ToString();
CurrentValueRecord current=entry.CurrentValues;
字符串newValue=current.GetValue(current.GetOrdinal(propertyName)).ToString();
if(oldValue!=newValue)//可能不需要
{
var a=string.Format(“条目:{0}原始:{1}新:{2}”,
entry.Entity.GetType().Name,
旧价值,新价值);
}
}
打破
}
}
}
返回base.saveChangesSync();
}
我还试图在Action方法中组合日志字符串,但我得到了相同的错误
public async Task<IActionResult> Edit(MyModel model)
{
...
// _context is ApplicationDbContext()
var myObjectState = _context.ObjectStateManager.GetObjectStateEntry(model);
var modifiedProperties = myObjectState.GetModifiedProperties();
foreach (var propName in modifiedProperties)
{
Console.WriteLine("Property {0} changed from {1} to {2}",
propName,
myObjectState.OriginalValues[propName],
myObjectState.CurrentValues[propName]);
}
}
公共异步任务编辑(MyModel)
{
...
//_上下文为ApplicationDbContext()
var myObjectState=_context.ObjectStateManager.GetObjectStateEntry(模型);
var modifiedProperties=myObjectState.GetModifiedProperties();
foreach(modifiedProperties中的变量propName)
{
WriteLine(“属性{0}从{1}更改为{2}”,
propName,
myObjectState.OriginalValues[propName],
myObjectState.CurrentValues[propName]);
}
}
我用的是EF6
我需要记录属性名、旧值和新值。我不明白为什么我会犯这样的错误,我做错了什么
我做错了什么
使用EF 4.1中的示例:)
你可以利用EF 6中的ChangeTracker来完成你想要的东西。我建议为日志设置一个单独的DbContext,根据需要只包含日志表和FK:
在SaveChanges/SaveChangesSync覆盖中:
var updatedEntities = ChangeTracker.Entries()
.Where(x => x.State == EntityState.Modified);
var insertedEntities = ChangeTracker.Entries()
.Where(x => x.State == EntityState.Added);
从这里,您可以分别通过OriginalValues
和CurrentValues
访问原始和修改的属性值
**更新**
报告更改时,典型的简单方法是对OriginalValues和CurrentValues使用ToObject()
,然后序列化为类似于Json的内容,以捕获相关对象的前后状态。但是,这将显示所有已修改和未修改的值
要遍历这些值以查找实际更改,需要更多的工作:
foreach(var entity in updatedEntities)
{
foreach (var propertyName in entity.OriginalValues.PropertyNames)
{
if (!object.Equals(entity.OriginalValues.GetValue<object>(propertyName),
entity.CurrentValues.GetValue<object>(propertyName)))
{
var columnName = propertyName;
var originalValue = entity.OriginalValues.GetValue<object>(propertyName)?.ToString() ?? "#null";
var updatedValue = entity.CurrentValues.GetValue<object>(propertyName)?.ToString() ?? "#null";
var message = $"The prop: {columnName} has been changed from {originalValue} to {updatedValue}";
}
}
}
foreach(updateTities中的var实体)
{
foreach(entity.OriginalValues.PropertyNames中的var propertyName)
{
如果(!object.Equals(entity.OriginalValues.GetValue(propertyName)),
entity.CurrentValues.GetValue(propertyName)))
{
var columnName=propertyName;
var originalValue=entity.OriginalValues.GetValue(propertyName)?.ToString()?“#null”;
var updatedValue=entity.CurrentValues.GetValue(propertyName)?.ToString()??“null”;
var message=$“属性:{columnName}已从{originalValue}更改为{updatedValue}”;
}
}
}
如何获取属性名称、旧值和新值?我做了一个foreach循环,其中我循环通过的每个实体,我试图组成如下字符串:string.Format(“prop:{0}已从{1}更改为{2}”、prop.ToString()、prop.OriginalValues、prop.CurrentValues)代码>我已在答案上展开,以提供用于生成更改历史记录的选项。OriginalValues不包含PropertyNames。我已经试过了。如果将整个对象传递给context.Update(objectToUpdate)
,会发生什么情况原始值和当前值是否相同?我使用的是EF 6,我可以从原始值中访问PropertyNames。确保您使用的是var updatedities=ChangeTracker.Entries(),其中(x=>x.State==EntityState.Modified)代码>。。如果您使用的是EF Core而不是EF 6,则原始值具有属性
,这些属性是包含.Name
属性的对象。我不建议使用context.Update(objectToUpdate)
,因为这会为所有列生成一条Update语句,无论它们是否更改。如果您想跟踪更新,最好让EF change tracker管理更新。
foreach(var entity in updatedEntities)
{
foreach (var propertyName in entity.OriginalValues.PropertyNames)
{
if (!object.Equals(entity.OriginalValues.GetValue<object>(propertyName),
entity.CurrentValues.GetValue<object>(propertyName)))
{
var columnName = propertyName;
var originalValue = entity.OriginalValues.GetValue<object>(propertyName)?.ToString() ?? "#null";
var updatedValue = entity.CurrentValues.GetValue<object>(propertyName)?.ToString() ?? "#null";
var message = $"The prop: {columnName} has been changed from {originalValue} to {updatedValue}";
}
}
}