Почему EF не сохраняет новое значение? - PullRequest
1 голос
/ 07 октября 2011

Вопрос: Почему этот код не сохраняет новое значение Summary в базе данных? Дайте мне знать, если я пропустил любой окружающий / релевантный код.

Детали:

У меня очень мало практического опыта работы с EF, и я только что унаследовал кодовую базу, которая широко его использует. Этот метод расширения находится в той кодовой базе, с использованием следующего:

public static void SafeAttachTo<T>(this ObjectContext context, string entitySetName, ref T entity) where T : IEntityWithKey {
            ObjectStateEntry entry; 
            bool attach;

            if (context.ObjectStateManager.TryGetObjectStateEntry(context.CreateEntityKey(entitySetName, entity), out entry)) {
                attach = entry.State == EntityState.Detached;
                entity = (T) entry.Entity;
            }
            else
                attach = true;

            if (attach) 
                context.AttachTo(entitySetName, entity);
        }

Использование:

    public int UpdateOrInsertWidget(Widget widget) {
        if (widget.Id == 0) {
            _context.Widgets.AddObject(widget);
        } else {
            _context.SafeAttachTo("Widgets", ref widget);
            _context.ObjectStateManager.ChangeObjectState(widget, EntityState.Modified);
        }

        return _context.SaveChanges();
    }

В какой-то момент пользователь изменяет Сводку на Widget (скажем, у типа есть свойства Id и Summary ... мы назовем этот экземпляр changedWidget) из "Старой Сводки" в «Новое резюме».

И так UpdateOrInsertWidget вызывается так:

UpdateOrInsertWidget(changedWidget);

После вызова _context.SaveChanges(); база данных (SQL Server 2008) отображает «Старое резюме» в столбце Сводка.

Строка entity = (T) entry.Entity;, кажется, перезаписывает changedWidget, когда она передается, что кажется плохим.

Но, без опыта EF, я изо всех сил пытаюсь понять, что в этом коде нужно изменить.

1 Ответ

2 голосов
/ 07 октября 2011

Я думаю, что проблема в том, что ваш метод расширения просто устанавливает ObjectStateEntry в состояние «Изменено», но ObjectStateEntry не знает , что изменилось.

Вместо этого вы должны использовать ApplyOriginalValues или ApplyCurrentValues, эти два метода применяют изменения от "отсоединенного" объекта к записи состояния объекта в существующем ObjectContext и сравнивают изменения так, чтобы ObjectContext знает, какие конкретные свойства были изменены.

Если вы присоединяете измененную сущность к контексту, то вам нужно ApplyOriginalValues, чтобы контекст мог видеть, что изменилось соригинал к тому, что он имеет сейчас.В противном случае вам нужно использовать ApplyCurrentValues.

. Подробнее вы можете прочитать здесь: http://msdn.microsoft.com/en-us/library/bb896248.aspx

...