Entity Framework ModelBinding - PullRequest
       3

Entity Framework ModelBinding

0 голосов
/ 07 июня 2011

Я уже давно борюсь с этой проблемой.Я просто не могу заставить мои объекты сущностей корректно обновляться при использовании UpdateModel ().

Я просто не вижу в этом сложной модели данных.Кажется, это должно быть очень распространенной ситуацией.Возможно, мне нужно кое-что добавить в контекст, чтобы беглый API устранил эту ошибку, но я не могу понять это на всю жизнь.

СООБЩЕНИЕ ОБ ОШИБКЕ

Операция завершилась неудачно: отношение не может быть изменено, поскольку одно или несколько свойств внешнего ключа не могут иметь значение NULL.Когда в отношение вносится изменение, для соответствующего свойства внешнего ключа устанавливается нулевое значение.Если внешний ключ не поддерживает нулевые значения, необходимо определить новое отношение, свойству внешнего ключа должно быть назначено другое ненулевое значение или несвязанный объект должен быть удален.

Здесьмои модели и контекст:

Контакт:

public class Contact {
    public Contact() {
      this.ContactInformations = new HashSet<ContactInformation>();
    }
    public int ContactId { get; set; }
    [Required]
    public string Firstname { get; set; }
    [Required]
    public string Lastname { get; set; }
    public virtual ICollection<ContactInformation> ContactInformations { get; set; }
  }

Контактная информация:

public class ContactInformation {
    public int ContactInformationId { get; set; }
    public int ContactTypeId { get; set; }
    public int ContactId { get; set; }
    [Required]
    public string Information { get; set; }
}

DatabaseContext:

public class Database : DbContext {

    public Database()
      : base("Contacts") {
    }

    public DbSet<Contact> Contacts { get; set; }
    public DbSet<ContactInformation> ContactInformations { get; set; }
}

Контроллер контактов.

    public ActionResult Edit(int id, Contact form) {
      var contact = db.Contacts.SingleOrDefault(c => c.ContactId == id);
      UpdateModel(contact);
      db.SaveChanges();
      return RedirectToAction("Index");
}

ФОРМА ДАННЫХ

[0] "ContactId"  
[1] "Firstname"    
[2] "Lastname"   
[3] "ContactInformations[0].Index" 
[4] "ContactInformations[0].ContactInformationId" 
[5] "ContactInformations[0].ContactId"    
[6] "ContactInformations[0].Information"    
[7] "ContactInformations[0].ContactTypeId"
[8] "ContactInformations[1].Index" 
[9] "ContactInformations[1].ContactInformationId" 
[10] "ContactInformations[1].ContactId"    
[11] "ContactInformations[1].Information"    
[12] "ContactInformations[1].ContactTypeId"

ОБНОВЛЕНИЕ связанная проблема с некоторыми интересными деталями к моей проблеме Здесь

1 Ответ

0 голосов
/ 07 июня 2011

Отношения в EF являются первоклассными сущностями.Поэтому, когда вы разрываете это соединение, вы должны (1) удалить связь и (2) удалить сущность.В этом коде:

  foreach (var item in needDeleted) {
    //have to use the datacontext directly.  I desperately want this gone!
    db.ContactInformations.Remove(db.ContactInformations.Single(c => c.ContactInformationId == item.ContactInformationId));

    //This will produce the same error as UpdateModel(contact)
    //contact.ContactInformations.Remove(contact.ContactInformations.SingleOrDefault(c => c.ContactInformationId == item.ContactInformationId));
  }

... вы делаете (1), но не (2).

Вы могли бы делать:

  foreach (var item in needDeleted) {
    var ci = contact.ContactInformations.Single(c => c.ContactInformationId == item.ContactInformationId);
    contact.ContactInformations.Remove(ci); // 1
    db.ContactInformations.Remove(ci);      // 2
  }

Тем не менее, более распространенным способом является наложение каскада на ФК и на поверхность его в вашей модели.В этом случае (1) будет работать сам по себе.

...