为什么我的审核跟踪代码会导致并发错误?

时间:2019-09-17 12:31:52

标签: oracle entity-framework .net-core entity-framework-core audit-trail

环境是React,.NET Core 2.2.5,Oracle EF Core 2.19.30,Oracle 12c。

每当以某种方式更改实体时,我都会使用以下代码添加更改日志条目。我在Google上看到的所有内容都表明这应该可行。但是,当它到达“ base.SaveChanges()”调用时,出现错误“数据库操作预期会影响1行但实际上会影响5行”。如果我删除更改日志代码并仅调用“ base.SaveChanges()”,它将正常工作并确实更新了预期的行,因此该问题显然与更改日志条目本身有关。

我已经在Google上看到此错误,但实际数字始终为0,再也没有。另一个奇怪的事情是,每当我运行代码时,“实际”数字就会增加5(目前我最多为95,这是我重新启动后的数字),而这恰好是更改日志条目的数量应该添加。

除了使用Oracle(我计划很快在家里使用SQL Server进行测试)之外,我没有发现任何异常情况。

    public override int SaveChanges()
    {
        List<EntityEntry> entries = ChangeTracker.Entries().Where(x => x.State == EntityState.Added || x.State == EntityState.Modified || x.State == EntityState.Deleted).ToList();

        foreach (EntityEntry entry in entries.ToArray())
        {
            string tableName = new SafetyDataContext().Model.FindEntityType(entry.Entity.GetType()).Relational().TableName;
            string keyData = GetPrimaryKeyValue(entry);

            if (entry.State == EntityState.Added)
            {
                PropertyValues currentValues = entry.CurrentValues;

                for (int i = 0; i < currentValues.Properties.Count; i++)
                {
                    string columnName = currentValues.Properties[i].Relational().ColumnName;
                    string newValue = currentValues[currentValues.Properties[i].Name] != null ? currentValues[currentValues.Properties[i].Name].ToString() : string.Empty;

                    EntityChangeModel log = new EntityChangeModel()
                    {
                        Change_Type = "ADD",
                        Change_Date = DateTime.Now,
                        Change_User_ID = 0,
                        Table_Name = tableName,
                        Column_Name = columnName,
                        Primary_Key = keyData,
                        Old_Value = string.Empty,
                        New_Value = newValue
                    };

                    this.Changes.Add(log);
                }
            }
            else if (entry.State == EntityState.Modified)
            {
                PropertyValues currentValues = entry.CurrentValues;
                PropertyValues originalValues = entry.OriginalValues;

                for (int i = 0; i < currentValues.Properties.Count; i++)
                {
                    string columnName = currentValues.Properties[i].Relational().ColumnName;
                    string oldValue = entry.GetDatabaseValues().GetValue<object>(originalValues.Properties[i].Name) != null ? entry.GetDatabaseValues().GetValue<object>(originalValues.Properties[i].Name).ToString() : string.Empty;
                    string newValue = currentValues[currentValues.Properties[i].Name] != null ? currentValues[currentValues.Properties[i].Name].ToString() : string.Empty;

                    if (oldValue != newValue)
                    {
                        EntityChangeModel log = new EntityChangeModel()
                        {
                            Change_Type = "CHANGE",
                            Change_Date = DateTime.Now,
                            Change_User_ID = 0,
                            Table_Name = tableName,
                            Column_Name = columnName,
                            Primary_Key = keyData,
                            Old_Value = oldValue,
                            New_Value = newValue
                        };

                        this.Changes.Add(log);
                    }
                }
            }
            else if (entry.State == EntityState.Deleted)
            {
                PropertyValues originalValues = entry.OriginalValues;

                for (int i = 0; i < originalValues.Properties.Count; i++)
                {
                    string columnName = originalValues.Properties[i].Relational().ColumnName;
                    string oldValue = entry.GetDatabaseValues().GetValue<object>(originalValues.Properties[i].Name) != null ? entry.GetDatabaseValues().GetValue<object>(originalValues.Properties[i].Name).ToString() : string.Empty;

                    EntityChangeModel log = new EntityChangeModel()
                    {
                        Change_Type = "DELETE",
                        Change_Date = DateTime.Now,
                        Change_User_ID = 0,
                        Table_Name = tableName,
                        Column_Name = columnName,
                        Primary_Key = keyData,
                        Old_Value = oldValue,
                        New_Value = string.Empty
                    };

                    this.Changes.Add(log);
                }
            }
        }

        return base.SaveChanges();
    }

0 个答案:

没有答案
相关问题