实体框架ModelBinding
本文关键字:ModelBinding 框架 实体 | 更新日期: 2023-09-27 17:58:39
我已经为这个问题挣扎了很长一段时间了。使用UpdateModel()时,我似乎无法正确更新实体对象。
我只是不认为这是一个复杂的数据模型。这似乎应该是一种非常常见的情况。也许我需要在fluent api的上下文中添加一些内容来消除这个错误,但我一辈子都无法解决。
错误消息
操作失败:由于一个或多个外键属性不可为null,因此无法更改关系。当对关系进行更改时,相关的外键属性将设置为null值。如果外键不支持null值,则必须定义新的关系,必须为外键属性分配另一个非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; }
}
数据库上下文:
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"
更新与我的问题有关的一些有趣的细节在这里
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)将自行工作。