我一直在努力解决这个问题已有一段时间了。在使用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
的一些有趣细节答案 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)将自行工作。