EF 4.1 SaveChanges не обновляет навигационные или ссылочные свойства

Сначала я использую код и могу добавлять записи без проблем. База данных создается должным образом и посеяна без каких-либо проблем. Но вызов SaveChanges() в моем действии редактирования только обновляет объект, а не свойства навигации или ссылки.

Упрощенная версия моей модели:

public class Contact : IMyBaseObject
{
    public Contact()
    {
       this.Delete = false;
       this.ContactTypes = new HashSet<ContactType>();
    }

    public int Id {get; set;}

    public string Name {get;set;}

    public bool Delete {get;set;}

    public virtual ICollection<ContactType> ContactTypes { get; set; }

    public virtual USState USState { get; set; }

}

public class ContactType : MyBaseObject
{
    public ContactType()
    {
    }

    public int Id {get; set;}

    public string Name {get;set;}

    public virtual ICollection<Contact> Contacts {get;set;}
}

public abstract class Territory : MyBaseObject
{
    public int Id {get; set;}

    public string Name {get;set;}

    public string Code {get;set;}
}

public class USState : Territory
{
    public USState()
    {
    }

    // Navigation properties
    public virtual ICollection<Contact> Contacts { get; set; }
}

Я не буду включать код, но у меня есть некоторые пользовательские привязки модели. Действие My Edit (с использованием MVC 3) не было заполнено свойствами ContactType или USState. Связывание корректно возвращает полностью заполненный объект Contact с правильными значениями из формы.

Если я правильно понимаю EF 4.1, мне нужно будет сделать следующее, чтобы сохранить изменения в базе данных при сохранении моего объекта Contact:

if(ModelState.IsValid)
{
    context.Entry(contact).State = EntryState.Modified;
    context.SaveChanges();
}

Однако, когда я это делаю, обновляются только примитивные свойства. В приведенном выше примере я пропустил несколько вещей: я использую транзакцию, блок catch try и проверяю, является ли это новой записью.

Я использовал SQL Profiler и могу подтвердить, что запросы на обновление для таблиц ContactType и Territory отправляются не на сервер базы данных.

Свойства свойства моих навигационных и ссылочных свойств изменены, но я также попытался вручную установить, что:

    context.Entry(contact).Collections("ContactTypes").EntityEntry.State = EntityState.Modified;
    context.Entry(contact).Reference("USState").EntityEntry.State = EntityState.Modified;

Я мог ошибаться, но я уверен, что мой код работает под CTP5.

Любые идеи? На этом этапе я не уверен, как мне следует отлаживать это.

Спасибо, Стив

Ответ 1

Попробуйте следующее:

  context.Entry(contact.USState ).State = EntityState.Modified; //////

Ответ 2

Предполагая, что ваши объекты DAL/Collection из Entity Framework, сделайте это:

Contact.ContactTypes.Load();

Это обновит соответствующий список coltactTypes из исходного источника.

Надеюсь, что это поможет.

Ответ 3

Предоставленный код может быть недостаточным. Лучше увидеть код, как свойства навигации были добавлены в код. Поскольку хотя родительский класс был помечен как измененный, это не означает, что соответствующие свойства навигации отмечены как добавленные или измененные. Самый быстрый способ - включить отладчик там, где был вызван .SaveChanges, а затем просмотреть контекстную переменную, изучить свойства "Локальный", а также, были ли доступны свойства навигации, также было ли добавлено или изменено их модальное состояние, затем будет намного легче сказать, что нужно сделать.

Ответ 4

Я уверен, что больше кода поможет лучше определить проблему, особенно код для привязки модели. но я думаю, что вы уже знакомы с тем, что вам нужно получить доступ к этим свойствам навигации (каким-то образом), поэтому EF сможет их автоматически загружать. Поскольку вы пометили свои навигационные свойства как виртуальные, вы разрешаете EF создавать прокси и переопределять ваши навигационные свойства, позволяющие Lazy Loading.