实体框架ModelBinding

时间:2011-06-07 15:40:43

标签: c# asp.net-mvc entity-framework ef-code-first

我一直在努力解决这个问题已有一段时间了。在使用UpdateModel()时,我似乎无法使我的实体对象正确更新。

我只是不认为这是一个复杂的数据模型。看来这应该是一种非常普遍的情况。也许我需要在上下文中添加一些内容,以便流畅的api消除这个错误,但我无法弄清楚我的生活。

错误消息

  

操作失败:无法更改关系,因为一个或多个外键属性不可为空。当对关系进行更改时,相关的外键属性将设置为空值。如果外键不支持空值,则必须定义新关系,必须为外键属性分配另一个非空值,或者必须删除不相关的对象。

以下是我的模型和背景:

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; }
  }

ContactInformation:

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"

更新 相关问题以及我的问题Here

的一些有趣细节

1 个答案:

答案 0 :(得分:0)

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
  }

然而,更常见的方法是在FK上放置一个级联并在模型中浮出表面。在这种情况下(1)将自行工作。