EF Core 在断开连接的场景中设置原始值
EF Core set Original Values in Disconnected Scenario
我正在使用 DBContext.Update(ParentEntity)
更新实体。然后我遍历每个实体 property.CurrentValue
和 property.OriginalValue
。
我面临的问题是 CurrentValues 和 OriginalValues 是相同的,即使一个 属性 已被更改并且与数据库不同.我期望从数据库中获取 OriginalValues。
这是保存更改之前发生的循环。
foreach (var entry in ChangeTracker.Entries())
{
if (entry.Entity is Audit || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged ||entry.Entity is ChangelogUser)
continue;
var auditEntry = new AuditEntry(entry) {TableName = entry.Metadata.Relational().TableName};
auditEntries.Add(auditEntry);
foreach (var property in entry.Properties)
{
if (property.IsTemporary)
{
// value will be generated by the database, get the value after saving
auditEntry.TemporaryProperties.Add(property);
continue;
}
string propertyName = property.Metadata.Name;
if (property.Metadata.IsPrimaryKey())
{
auditEntry.KeyValues[propertyName] = property.CurrentValue;
continue;
}
switch (entry.State)
{
case EntityState.Added:
auditEntry.NewValues[propertyName] = property.CurrentValue;
break;
case EntityState.Deleted:
auditEntry.OldValues[propertyName] = property.OriginalValue;
break;
case EntityState.Modified:
if (property.CurrentValue != null)
{
if (property.OriginalValue != null && property.CurrentValue != null)
{
if (property.IsModified && !property.CurrentValue.Equals(property.OriginalValue))
{
auditEntry.OldValues[propertyName] = property.OriginalValue;
auditEntry.NewValues[propertyName] = property.CurrentValue;
}
}
}
break;
}
}
从这段代码中,我 AWLAYS 得到了相同的原始值和当前值。有没有办法从数据库中获取原始值并将它们设置在实体上?
由于很难找到 EFCore 问题的答案,所以这里是我想出的解决方案。
查看 State.Modified 部分。我遍历每个实体,然后遍历每个 属性。在这种情况下,我使用当前值和原始值来比较它们,并且仅在发生变化时才将它们添加到我的审计 table 中。
在方法的结尾,我删除了未从我的审核中更改的实体table。简单的米普尔。
您可以使用此 var databaseValues = entry.GetDatabaseValues();
来满足您的自定义断开连接场景需求。
var auditEntries = new List<AuditEntry>();
foreach (var entry in ChangeTracker.Entries())
{
if (entry.Entity is Audit || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged)
continue;
var auditEntry = new AuditEntry(entry) {TableName = entry.Metadata.Relational().TableName};
auditEntries.Add(auditEntry);
var databaseValues = entry.GetDatabaseValues();
foreach (var property in entry.Properties)
{
if (property.IsTemporary)
{
// value will be generated by the database, get the value after saving
auditEntry.TemporaryProperties.Add(property);
continue;
}
string propertyName = property.Metadata.Name;
if (property.Metadata.IsPrimaryKey())
{
auditEntry.KeyValues[propertyName] = property.CurrentValue;
continue;
}
switch (entry.State)
{
case EntityState.Added:
auditEntry.NewValues[propertyName] = property.CurrentValue;
break;
case EntityState.Deleted:
auditEntry.OldValues[propertyName] = property.OriginalValue;
break;
case EntityState.Modified:
if (property.CurrentValue != null)
{
if (databaseValues[propertyName] != null && property.CurrentValue != null)
{
if (property.IsModified && !property.CurrentValue.Equals(databaseValues[propertyName]))
{
auditEntry.OldValues[propertyName] = databaseValues[propertyName];
auditEntry.NewValues[propertyName] = property.CurrentValue;
}
}
}
break;
}
}
if (auditEntry.NewValues.Equals(auditEntry.OldValues) || auditEntry.NewValues.Count == 0 && auditEntry.OldValues.Count == 0)
{
auditEntries.Remove(auditEntry);
}
我正在使用 DBContext.Update(ParentEntity)
更新实体。然后我遍历每个实体 property.CurrentValue
和 property.OriginalValue
。
我面临的问题是 CurrentValues 和 OriginalValues 是相同的,即使一个 属性 已被更改并且与数据库不同.我期望从数据库中获取 OriginalValues。
这是保存更改之前发生的循环。
foreach (var entry in ChangeTracker.Entries())
{
if (entry.Entity is Audit || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged ||entry.Entity is ChangelogUser)
continue;
var auditEntry = new AuditEntry(entry) {TableName = entry.Metadata.Relational().TableName};
auditEntries.Add(auditEntry);
foreach (var property in entry.Properties)
{
if (property.IsTemporary)
{
// value will be generated by the database, get the value after saving
auditEntry.TemporaryProperties.Add(property);
continue;
}
string propertyName = property.Metadata.Name;
if (property.Metadata.IsPrimaryKey())
{
auditEntry.KeyValues[propertyName] = property.CurrentValue;
continue;
}
switch (entry.State)
{
case EntityState.Added:
auditEntry.NewValues[propertyName] = property.CurrentValue;
break;
case EntityState.Deleted:
auditEntry.OldValues[propertyName] = property.OriginalValue;
break;
case EntityState.Modified:
if (property.CurrentValue != null)
{
if (property.OriginalValue != null && property.CurrentValue != null)
{
if (property.IsModified && !property.CurrentValue.Equals(property.OriginalValue))
{
auditEntry.OldValues[propertyName] = property.OriginalValue;
auditEntry.NewValues[propertyName] = property.CurrentValue;
}
}
}
break;
}
}
从这段代码中,我 AWLAYS 得到了相同的原始值和当前值。有没有办法从数据库中获取原始值并将它们设置在实体上?
由于很难找到 EFCore 问题的答案,所以这里是我想出的解决方案。
查看 State.Modified 部分。我遍历每个实体,然后遍历每个 属性。在这种情况下,我使用当前值和原始值来比较它们,并且仅在发生变化时才将它们添加到我的审计 table 中。
在方法的结尾,我删除了未从我的审核中更改的实体table。简单的米普尔。
您可以使用此 var databaseValues = entry.GetDatabaseValues();
来满足您的自定义断开连接场景需求。
var auditEntries = new List<AuditEntry>();
foreach (var entry in ChangeTracker.Entries())
{
if (entry.Entity is Audit || entry.State == EntityState.Detached || entry.State == EntityState.Unchanged)
continue;
var auditEntry = new AuditEntry(entry) {TableName = entry.Metadata.Relational().TableName};
auditEntries.Add(auditEntry);
var databaseValues = entry.GetDatabaseValues();
foreach (var property in entry.Properties)
{
if (property.IsTemporary)
{
// value will be generated by the database, get the value after saving
auditEntry.TemporaryProperties.Add(property);
continue;
}
string propertyName = property.Metadata.Name;
if (property.Metadata.IsPrimaryKey())
{
auditEntry.KeyValues[propertyName] = property.CurrentValue;
continue;
}
switch (entry.State)
{
case EntityState.Added:
auditEntry.NewValues[propertyName] = property.CurrentValue;
break;
case EntityState.Deleted:
auditEntry.OldValues[propertyName] = property.OriginalValue;
break;
case EntityState.Modified:
if (property.CurrentValue != null)
{
if (databaseValues[propertyName] != null && property.CurrentValue != null)
{
if (property.IsModified && !property.CurrentValue.Equals(databaseValues[propertyName]))
{
auditEntry.OldValues[propertyName] = databaseValues[propertyName];
auditEntry.NewValues[propertyName] = property.CurrentValue;
}
}
}
break;
}
}
if (auditEntry.NewValues.Equals(auditEntry.OldValues) || auditEntry.NewValues.Count == 0 && auditEntry.OldValues.Count == 0)
{
auditEntries.Remove(auditEntry);
}