2

次の拡張メソッドがありますが、1 つのエントリを呼び出した後、各エントリの状態が Unchanged に変更される理由がわかりませんentry.AcceptChanges()

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

私は何か間違ったことをしていますか?

4

2 に答える 2

1

はい、その通りです。ObjectStateEntry.AcceptChangesは、特定のエンティティにのみ影響することを除いて、 ObjectContext.AcceptAllChangesに似ています。 重要な点は、デフォルトでは、SaveChangesメソッドがデータベースの変更を実行した後にAcceptAllChangesメソッドを呼び出すことです。次に、AcceptAllChangesは、アタッチされているすべてのエンティティの現在の値を元の値にプッシュしてから、 EntityStateUnchangedに変更します。 ご覧のとおり、問題はcontext.SaveChanges()という事実に起因しています。



foreachの最初の反復で呼び出されるため、AcceptAllChanges()がSaveChanges()によって呼び出され、全員がUnchanged状態になります。

于 2010-10-01T20:33:05.840 に答える
0

AcceptChangesメソッドは、仕様によりこれを行います。
どのような動作を期待していますか?

于 2010-10-01T15:54:42.703 に答える