Странное поведение с состоянием ObjectStateEntry - PullRequest
2 голосов
/ 30 сентября 2010

У меня есть следующий метод расширения, и я не уверен, почему каждое состояние записи изменяется на Неизменный после того, как я вызываю 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();
        }
    }

Я что-то делаю неправильно?

Ответы [ 2 ]

1 голос
/ 02 октября 2010

Да, это правильно. ObjectStateEntry.AcceptChanges аналогично ObjectContext.AcceptAllChanges , , за исключением , которое будет воздействует только на конкретную сущность .

Важным моментом является то, что по умолчанию метод SaveChanges вызывает AcceptAllChanges метод после выполнения базы данныхмодификаций.Затем AcceptAllChanges помещает текущие значения каждого присоединенного объекта в исходные значения, а затем изменяет их EntityState на Без изменений .

Как видите, ваша проблема связана с тем, что context.SaveChanges () вызывается на первой итерации вашего foreach , поэтому AcceptAllChanges () вызывается SaveChanges () , и это заставляет всех переходить в неизменное состояние.

0 голосов
/ 01 октября 2010

Метод AcceptChanges делает это специально.
Какое поведение вы ожидаете?

...