ObjectStateEntry状态的奇怪行为

时间:2010-09-30 17:48:30

标签: logging .net-4.0 entity-framework-4 objectcontext

我有以下扩展方法,并且我不确定为什么在我在一个条目上调用entry.AcceptChanges()后,每个条目状态都被更改为Unchanged。

    public static void SaveWithLogging(this ObjectContext context)
    {
        IEnumerable<ObjectStateEntry> entries = context.ObjectStateManager.GetObjectStateEntries(EntityState.Modified | EntityState.Added | EntityState.Deleted);
        foreach (var entry in entries)
            CreateTransactionLog(context, entry);
    }


    private static void CreateTransactionLog(ObjectContext context, ObjectStateEntry entry)
    {
        using (TransactionScope transaction = new TransactionScope())
        {

            string operationType = entry.State.ToString();

            context.SaveChanges(SaveOptions.DetectChangesBeforeSave);
            if (entry.State == EntityState.Added) entry.AcceptChanges();

            var columnNames = (from p in entry.EntitySet.ElementType.Members
                               select p.Name)
                               .ToList();

            Log log = new Log();
            log.CreateDate= DateTime.Now;
            log.UserName = "Test";
            log.Operation = operationType;
            context.AddObject("Logs", log);

            foreach (var columnName in columnNames)
            {
                string oldValue = entry.State == EntityState.Added ? string.Empty : entry.OriginalValues[columnName].ToString();
                string newValue = entry.CurrentValues[columnName].ToString();
                if (oldValue.CompareTo(newValue) != 0)
                {
                    // Create Log Details
                    LogDetail logDetails = LogDetail();
                    logDetails.LogId = log.LogId;
                    logDetails.TableName = entry.EntitySet.Name.ToString();
                    logDetails.Field = columnName.ToString();
                    logDetails.Before = oldValue;
                    logDetails.After = newValue;
                    logDetails.PKValue = entry.CurrentValues[0].ToString();
                    context.AddObject("LogDetails", logDetails);
                }
            }
            context.SaveChanges();
            transaction.Complete();
        }
    }

我做错了什么?

2 个答案:

答案 0 :(得分:1)

是的,这是正确的。 ObjectStateEntry.AcceptChanges 类似于 ObjectContext.AcceptAllChanges 之外影响只有特定的实体

重要的是,默认情况下, SaveChanges 方法在执行数据库修改后调用 AcceptAllChanges 方法。然后 AcceptAllChanges 每个附加实体的当前值推送到原始值,然后将 EntityState 更改为 Unchanged

正如您所看到的,您的问题来自 context.SaveChanges() foreach 的第一次迭代时被调用的事实,因此 AcceptAllChanges()< / em>由 SaveChanges()调用,使每个人都进入 Unchanged 状态。

答案 1 :(得分:0)

AcceptChanges方法通过设计实现此目的 你期待什么行为?