Принудительное использование кода EF 4.1 первым, чтобы увидеть присоединенный объект как измененный - PullRequest
21 голосов
/ 11 декабря 2010

Все примеры, которые я нашел, относятся к классу с именем ObjectContext, которого нет в CTP5. Я должен подчеркнуть, что CTP5 - это мое первое знакомство с Entity Framework.

У меня есть отключенное POCO, которое я прикрепил к своему DbContext. SaveChanges не принимает изменения, хотя, как я говорю моему контексту, чтобы обновить эту сущность?

_context.Users.Attach(user);
// The user has been replaced.
_context.SaveChanges();
// The change is not saved.

Что я делаю не так?

Обновление 12.01.2011 Может показаться очевидным для большинства, но как первый пользователь EF, мне не пришло в голову, что присоединение уже присоединенного объекта очистит предыдущее состояние. Это причинило мне много боли. Но я хотел использовать шаблон Repository очень общим способом, который не заботился о том, был ли объект уже присоединен или был заново создан в результате привязки ASP.NET MVC. Поэтому мне понадобился метод UpdateUser, и я прикрепил его ниже.

    public User UpdateUser(User user) {
        if (_context.Entry(user).State == EntityState.Detached) {
            _context.Users.Attach(user);
            _context.Entry(user).State = EntityState.Modified;
        }
        return user;
    }

Метод, очевидно, предполагает, что объект существует в хранилище данных каким-то образом, в конце концов, он называется UpdateUser. Если объект уже подключен, вы извлечете выгоду из предыдущего состояния объекта, что, в свою очередь, позволит оптимизировать обновление БД. Однако, если объект не был прикреплен, метод заставляет все это стать грязным.

Кажется очевидным сейчас, не раньше. Надеюсь, это кому-нибудь поможет.

Rich

Ответы [ 3 ]

29 голосов
/ 11 декабря 2010

Когда вы присоединяете сущность, она переходит в неизменное состояние (оно не изменялось с момента его присоединения к контексту).Все, что вам нужно, это явно изменить состояние объекта на Изменено :

_context.Users.Attach(user);
_context.Entry(user).State = System.Data.Entity.EntityState.Modified;
_context.SaveChanges();
4 голосов
/ 20 декабря 2010

Ради полноты вы можете получить доступ к ObjectContext, приведя DbContext к IObjectContextAdapter:

((IObjectContextAdapter)context).ObjectContext.ObjectStateManager.ChangeObjectState(user, EntityState.Modified);

Метод Мортезы намного чище и получает мой голос.

2 голосов
/ 17 января 2011

Я считаю, что вам не нужно прикреплять объект, прежде чем вы измените вызов.просто установка на измененное сделает работу.

if (_context.Entry(user).State == EntityState.Detached)
{
    _context.Entry(user).State = EntityState.Modified;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...