ChangeTracker.Entries() CurrentValue 等于 EF7 中的 OriginalValue
ChangeTracker.Entries() CurrentValue equals OriginalValue in EF7
我在 EF7/asp.Net Core 应用程序中遇到问题。在我的上下文中,我创建了一个方法 Save:
public int Save()
{
ChangeTracker.DetectChanges();
var modifiedEntities = ChangeTracker.Entries()
.Where(p => p.State == EntityState.Modified || p.State == EntityState.Added || p.State == EntityState.Deleted || p.State == EntityState.Modified || p.State == EntityState.Detached).ToList();
var now = DateTime.UtcNow;
foreach (var change in modifiedEntities)
{
var entityName = change.Entity.GetType().Name;
var primaryKeyValue = GetPrimaryKeyValue(change.Entity);
foreach (var prop in change.Entity.GetType().GetTypeInfo().DeclaredProperties)
{
if (!prop.GetGetMethod().IsVirtual)
{
var currentValue = change.Property(prop.Name).CurrentValue;
var originalValue = change.Property(prop.Name).OriginalValue;
if (originalValue.ToString() != currentValue.ToString())
{
var changeLoged = new ChangeLog
{
PropertyName = prop.Name,
EntityName = entityName,
PrimaryKeyValue = primaryKeyValue,
DateChange = now,
OldValue = originalValue.ToString(),
NewValue = currentValue.ToString(),
ChangedBy = "test"
};
ChangeLog.Add(changeLoged);
}
}
}
}
return base.SaveChanges();
}
和方法 GetPrimaryKeyValue:
protected virtual int GetPrimaryKeyValue<T>(T entity)
{
var test = entity;
var test2 = test.GetType();
var keyName = this.Model.FindEntityType(test2).FindPrimaryKey().Properties
.Select(x => x.Name).Single();
var result = (int)entity.GetType().GetProperty(keyName).GetValue(entity, null);
if (result < 0)
return -1;
return result;
}
不幸的是 change.Property(prop.Name).CurrentValue 总是等于 OriginalValue,所以如果
originalValue.ToString() != currentValue.ToString()
总是return错误。
这不会完全回答你的问题,因为我无法重现这个问题,但这可能会对你有所帮助。
在 EF Core 中,PropertyEntry class 现在有一个 IsModified 属性,如果该值是否已修改。
你应该改用它:
if (change.Property(prop.Name).IsModified)
{
var changeLoged = new ChangeLog
{
PropertyName = prop.Name,
EntityName = entityName,
PrimaryKeyValue = primaryKeyValue,
DateChange = now,
OldValue = originalValue.ToString(),
NewValue = currentValue.ToString(),
ChangedBy = "test"
};
ChangeLog.Add(changeLoged);
}
免责声明:我是项目的所有者Entity Framework Plus
库有一个审计功能(支持 EF Core),您可以使用它或从中获得灵感来创建您的审计(代码是开源的)。
文档:EF+ Audit
替换:
var originalValue = change.Property(prop.Name).OriginalValue;
至:
var originalValue = change.GetDatabaseValues().GetValue<object>(prop.Name);
我在 EF7/asp.Net Core 应用程序中遇到问题。在我的上下文中,我创建了一个方法 Save:
public int Save()
{
ChangeTracker.DetectChanges();
var modifiedEntities = ChangeTracker.Entries()
.Where(p => p.State == EntityState.Modified || p.State == EntityState.Added || p.State == EntityState.Deleted || p.State == EntityState.Modified || p.State == EntityState.Detached).ToList();
var now = DateTime.UtcNow;
foreach (var change in modifiedEntities)
{
var entityName = change.Entity.GetType().Name;
var primaryKeyValue = GetPrimaryKeyValue(change.Entity);
foreach (var prop in change.Entity.GetType().GetTypeInfo().DeclaredProperties)
{
if (!prop.GetGetMethod().IsVirtual)
{
var currentValue = change.Property(prop.Name).CurrentValue;
var originalValue = change.Property(prop.Name).OriginalValue;
if (originalValue.ToString() != currentValue.ToString())
{
var changeLoged = new ChangeLog
{
PropertyName = prop.Name,
EntityName = entityName,
PrimaryKeyValue = primaryKeyValue,
DateChange = now,
OldValue = originalValue.ToString(),
NewValue = currentValue.ToString(),
ChangedBy = "test"
};
ChangeLog.Add(changeLoged);
}
}
}
}
return base.SaveChanges();
}
和方法 GetPrimaryKeyValue:
protected virtual int GetPrimaryKeyValue<T>(T entity)
{
var test = entity;
var test2 = test.GetType();
var keyName = this.Model.FindEntityType(test2).FindPrimaryKey().Properties
.Select(x => x.Name).Single();
var result = (int)entity.GetType().GetProperty(keyName).GetValue(entity, null);
if (result < 0)
return -1;
return result;
}
不幸的是 change.Property(prop.Name).CurrentValue 总是等于 OriginalValue,所以如果
originalValue.ToString() != currentValue.ToString()
总是return错误。
这不会完全回答你的问题,因为我无法重现这个问题,但这可能会对你有所帮助。
在 EF Core 中,PropertyEntry class 现在有一个 IsModified 属性,如果该值是否已修改。
你应该改用它:
if (change.Property(prop.Name).IsModified)
{
var changeLoged = new ChangeLog
{
PropertyName = prop.Name,
EntityName = entityName,
PrimaryKeyValue = primaryKeyValue,
DateChange = now,
OldValue = originalValue.ToString(),
NewValue = currentValue.ToString(),
ChangedBy = "test"
};
ChangeLog.Add(changeLoged);
}
免责声明:我是项目的所有者Entity Framework Plus
库有一个审计功能(支持 EF Core),您可以使用它或从中获得灵感来创建您的审计(代码是开源的)。
文档:EF+ Audit
替换:
var originalValue = change.Property(prop.Name).OriginalValue;
至:
var originalValue = change.GetDatabaseValues().GetValue<object>(prop.Name);