【问题标题】:Better Way to Create an Audit Trail Using Entity Framework使用实体框架创建审计跟踪的更好方法
【发布时间】:2018-05-15 11:32:24
【问题描述】:

我查看了许多使用实体框架创建审计跟踪的示例,但尚未找到适合我的任何内容。通过简单地覆盖数据库上下文中的 SaveChanges 并使用 ChangeTracker 必须有一种巧妙/简洁的方法来做到这一点......我遇到的问题是诸如添加(创建)一个实体时它直到之后才具有 ID你保存它,当你保存它时,它似乎会爆炸更改跟踪器中的内容。无论如何,我有一个审计跟踪工作,但它很丑陋,我正在寻求帮助来简化它并使其不必每次添加实体时都添加一个可怕的 if-then !任何和所有帮助表示赞赏。

    public bool CreateRecord(object o)
    {
        Audit audit = new Audit()
        {
            ChangeTypeID = (int)Audit.ChangeType.CREATE,
            TimeStamp = GetCurrentDateTime(),
            RecordClass = o.GetType().ToString(),
            NewValue = "",
            ReasonForChange = "Record Creation"
        };

        if (o.GetType() == typeof(Permission))
        {
            Permission x = (Permission)o;
            audit.OriginalValue = x.ToString();
            Permissions.Add(x);
            SaveChanges();
            audit.RecordID = x.ID;
        }
        else if (o.GetType() == typeof(User))
        {
            User x = (User)o;
            audit.OriginalValue = x.ToString();
            Users.Add(x);
            SaveChanges();
            audit.RecordID = x.ID;
        }
        else if (o.GetType() == typeof(LogIn))
        {
            LogIn x = (LogIn)o;
            audit.OriginalValue = x.ToString();
            LogIns.Add(x);
            SaveChanges();
            audit.RecordID = x.ID;
        }
        else if (o.GetType() == typeof(Marker))
        {
            Marker x = (Marker)o;
            audit.OriginalValue = x.ToString();
            Markers.Add(x);
            SaveChanges();
            audit.RecordID = x.ID;
        }
        else if (o.GetType() == typeof(Method))
        {
            Method x = (Method)o;
            audit.OriginalValue = x.ToString();
            Methods.Add(x);
            SaveChanges();
            audit.RecordID = x.ID;
        }
        else if (o.GetType() == typeof(Sample))
        {
            Sample x = (Sample)o;
            audit.OriginalValue = x.ToString();
            Samples.Add(x);
            SaveChanges();
            audit.RecordID = x.ID;
        }
        else if (o.GetType() == typeof(Run))
        {
            Run x = (Run)o;
            audit.OriginalValue = x.ToString();
            Runs.Add(x);
            SaveChanges();
            audit.RecordID = x.ID;
        }
        else if (o.GetType() == typeof(XYDataSet))
        {
            XYDataSet x = (XYDataSet)o;
            audit.OriginalValue = x.ToString();
            XYDataSets.Add(x);
            SaveChanges();
            audit.RecordID = x.ID;
        }
        else
        {
            return false;
        }

        // Save audit record
        audit.UserID = ((App)Application.Current).GetCurrentUserID();
        Audits.Add(audit);
        SaveChanges();

        return true;
    }

【问题讨论】:

标签: entity-framework audit change-tracking


【解决方案1】:

我假设所有实体都属于同一个项目/程序集,因此您可以尝试类似的方法并注意此代码未经测试,可能需要修改。

    public bool CreateRecord(object o)
    {
        Audit audit = new Audit()
        {
            ChangeTypeID = (int)Audit.ChangeType.CREATE,
            TimeStamp = GetCurrentDateTime(),
            RecordClass = o.GetType().ToString(),
            NewValue = "",
            ReasonForChange = "Record Creation"
        };
        var entityType = Assembly.GetAssembly(typeof(Permission)).GetTypes().Where(x => x == o.GetType())
            .FirstOrDefault(); // Determine the desired entity (assumed all of the entities belongs to same project/assembly)
        if (entityType != null)
        {
            var convertedObject = Convert.ChangeType(o, entityType); // Convert object to entity
            audit.OriginalValue = convertedObject.ToString();
            var entity = yourContext.Set(entityType).Add(convertedObject); // Get DbSet for casted entity
            SaveChanges();
            audit.RecordID = x.ID;
        }
        else
        {
            return false;
        }

        // Save audit record
        audit.UserID = ((App)Application.Current).GetCurrentUserID();
        Audits.Add(audit);
        SaveChanges();

        return true;
    }

【讨论】:

  • 非常非常感谢!这让我走了90%的路。唯一的问题是,在我的每个实体中,我都有一个 ID 主键。在您上面的代码中,您留下了我的残留(现在未声明)x 变量“audit.RecordID = x.ID”。基本上我保存了实体的类型和主键 ID,以便我可以从审计跟踪中返回任何实体。所以我的后续问题是我们如何从转换后的对象中提取 ID? (再次感谢您的帮助!!!)
  • 不客气。你会这样尝试吗? "var id = entityType.GetProperty("ID").GetValue(convertedObject, null);"
猜你喜欢
  • 2014-12-08
  • 2014-01-24
  • 1970-01-01
  • 2011-04-23
  • 2014-01-28
  • 2011-04-05
  • 2020-01-01
  • 2011-08-27
  • 1970-01-01
相关资源
最近更新 更多