EF Core在断开连接的情况下设置原始值

时间:2019-04-26 09:45:34

标签: ef-core-2.2

我正在使用DBContext.Update(ParentEntity)更新实体。然后,我遍历每个实体property.CurrentValueproperty.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获得相同的原始值和当前值。有什么方法可以从数据库获取原始值并将其设置在实体上?

1 个答案:

答案 0 :(得分:0)

由于很难获得EFCore问题的答案,所以这是我想出的解决方案。

查看已修改状态部分。我遍历每个实体,然后遍历每个属性。在这种情况下,我将使用当前值和原始值进行比较,并且仅在发生更改时才将它们添加到我的审核表中。

在方法的结束中,我从审计表中删除了未更改的实体。简单的傻瓜。

您可以使用var databaseValues = entry.GetDatabaseValues(); To来满足您的自定义断开连接方案的需求。

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);
            }