Entity Framework POCO SaveChanges() при обновлении не работает?

Я работаю с EF CTP 4, использую модели POCO, добавляю новый объект и вызываю SaveChanges(), но обновление объекта не работает. Вот код для обновления:

public void UpdateContact(Contact contact)
        {
            var findContact = GetContact(contact.ContactID);
            findContact = contact;
            _context.SaveChanges();
        }

public Contact GetContact(int contactId)
        {
            return GetAllContacts().SingleOrDefault(c => c.ContactID == contactId);
        }

public IQueryable<Contact> GetAllContacts()
        {
            return _context.Contacts;
        }

Я не уверен, что я делаю неправильно здесь. Любая идея? Спасибо.


person Saxman    schedule 02.11.2010    source источник


Ответы (1)


Проблема в том, что когда вы назначаете findContact = contact, EntityState не изменяется в ObjectStateManager (поэтому он по-прежнему установлен на Unchanged). Поэтому для объекта не создается оператор Update SQL. У вас есть несколько вариантов обновления:

Вариант 1. Заполните findContact поле за полем:

var findContact = GetContact(contact.ContactID);
findContact.FirstName = contact.FirstName;
findContact.LastName = contact.LastName;
...
_context.SaveChanges();

Вариант 2. Используйте метод ApplyCurrentValues:

var findContact = GetContact(contact.ContactID);
_context.ApplyCurrentValues("Contacts", contact);
_context.SaveChanges();

Вариант 3. Прикрепите обновленный объект и измените состояние в файле ObjectStateManager. (Примечание: при этом не будет выполняться обращение к базе данных для извлечения существующего контакта).

_context.AttachTo("Contacts", contact);
var contactEntry = Context.ObjectStateManager.GetObjectStateEntry(contact);
contactEntry.ChangeState(EntityState.Modified);
_context.SaveChanges();
person Yakimych    schedule 02.11.2010
comment
Привет, Якимыч, с вариантом 1, могу ли я использовать AutoMapper для сопоставления между findContact и contact вместо сопоставления каждого свойства? Спасибо. - person Saxman; 02.11.2010
comment
@Saxman - хотя AutoMapper обычно используется для сопоставления объектов разных типов, вы можете попробовать использовать один и тот же тип на обеих сторонах сопоставления. Сам не пользовался, но можно попробовать. И, пожалуйста, опубликуйте обновление после того, как вы решите проблему - это может быть полезно для дальнейшего использования. - person Yakimych; 02.11.2010
comment
По какой-то причине я не могу вызвать метод ApplyCurrentValues() с моим контекстом, поэтому вариант 2 исключен. Вариант 3 не пробовал. AutoMapper в этой ситуации не сработал, приходится вручную выставлять свойства findContact равными контакту. Спасибо! - person Saxman; 03.11.2010