如何存储原始值EF4.0 Audit Trail

时间:2013-12-02 11:43:55

标签: c# winforms entity-framework

我正在尝试在ef4.0中进行审计跟踪,我正在尝试存储原始值,我的问题是我对实体的任何引用都将在保存更改时保存。我是否可以访问原始值保存更改后的实体称为我一直在尝试使用此方法。

    public static object DeepCopy(object obj)
        {
            if (obj == null)
                return null;
            Type type = obj.GetType();

            if (type.IsValueType || type == typeof(string))
            {
                return obj;
            }
            else if (type.IsArray)
            {
                Type elementType = Type.GetType(
                     type.FullName.Replace("[]", string.Empty));
                var array = obj as Array;
                Array copied = Array.CreateInstance(elementType, array.Length);
                for (int i = 0; i < array.Length; i++)
                {
                    copied.SetValue(DeepCopy(array.GetValue(i)), i);
                }
                return Convert.ChangeType(copied, obj.GetType());
            }
            else if (type.IsClass)
            {

                object toret = Activator.CreateInstance(obj.GetType());
                FieldInfo[] fields = type.GetFields(BindingFlags.Public |
                            BindingFlags.NonPublic | BindingFlags.Instance);
                foreach (FieldInfo field in fields)
                {
                    object fieldValue = field.GetValue(obj);
                    if (fieldValue == null)
                        continue;
                    field.SetValue(toret, DeepCopy(fieldValue));
                }
                return toret;
            }
            else
                throw new ArgumentException("Unknown type");
        }

            private void AddStatusHistoryRecord(string notes)
            {
                try
                {
                    if (absenceEntity.ess_absence_history == null)
                    {
                        if (statusHistory == null)
                            statusHistory = new List<AbsenceStatusHistoryList>();

                        statusHistory.Add(new AbsenceStatusHistoryList(userId, userName, 3, 3, DateTime.Now, notes));

                        EmployeeAbsenceStatusHistory history = new EmployeeAbsenceStatusHistory();
                        history.absence = absenceEntity;
                        history.history_xml = GetStatusHistoryXml();
                       if(isEdit  == false)
                            pamsContext.AddAbsenceStatusHistory(history);
                       if (isEdit == true)
                           grdStatusHistory.CurrentRow.Cells["Notes"].Value = notes;
                    }
                    else
                    {
                        if (statusHistory == null)
                            GetStatusHistoryRecords();
                        if (isEdit == false) 
                            statusHistory.Add(new AbsenceStatusHistoryList(userId, userName, 3, 3, DateTime.Now, notes));
                        if (isEdit == true)
                            grdStatusHistory.CurrentRow.Cells["Notes"].Value = notes;

                        absenceEntity.ess_absence_history.history_xml = GetStatusHistoryXml();
                    }
                }
                catch (Exception ex)
                {
                    ExceptionBox.Show("An error occurred in the AddStatusHistoryRecord method.", ex);
                }
            }

1 个答案:

答案 0 :(得分:0)

我认为您需要在保存之前访问changeTracker。我希望在成功SaveChanges之后,状态为modified的所有实体都处于状态unchanged

有关objectContext访问权限,请参阅https://stackoverflow.com/a/6730415/1347784以更改跟踪器。

示例上下文转储工具。这使用DBContext而不是Objectcontext,因此如果您只访问ObjectContext,则需要更改。 ef4.0只是Objectcontext? 如果它有帮助...

 public static void ContextDumpTest(DbContext context)
    {

        Debug.WriteLine("=====Begin of Context Dump=======");
        var dbsetList = context.ChangeTracker.Entries();
        foreach (var dbEntityEntry in dbsetList)
        {

            Debug.WriteLine(dbEntityEntry.Entity.GetType().Name + " => " + dbEntityEntry.State);
            switch (dbEntityEntry.State)
            {
                case EntityState.Detached:
                case EntityState.Unchanged:
                case EntityState.Added:
                case EntityState.Modified:
                    WriteValuesPairs(dbEntityEntry);
                    break;
                case EntityState.Deleted:
                    WriteOriginalValues(dbEntityEntry);
                    break;
                default:
                    throw new ArgumentOutOfRangeException();
            }
            Debug.WriteLine("==========End of Entity======");
        }
        Debug.WriteLine("==========End of Context======");
    }
    private static void WriteValuesPairs(DbEntityEntry dbEntityEntry)
    {
        foreach (var cv in dbEntityEntry.OriginalValues.PropertyNames)
        {
            if (dbEntityEntry.OriginalValues[cv] == null && dbEntityEntry.CurrentValues[cv] == null) {
                Debug.WriteLine(cv + " Unchanged: " + "null"); 
            }
            else 
            if  (dbEntityEntry.OriginalValues[cv] != null && dbEntityEntry.CurrentValues[cv] != null
                  &&  dbEntityEntry.OriginalValues[cv].Equals(dbEntityEntry.CurrentValues[cv]) ) {
                Debug.WriteLine(cv + " Unchanged: " + dbEntityEntry.OriginalValues[cv]);
            }
            else {
                Debug.WriteLine(cv + " Original= " + dbEntityEntry.OriginalValues[cv] + "-> New= " + dbEntityEntry.CurrentValues[cv]);    
            }


        }
    }