I've been struggling with this problem for quite some time now. I just can't seem to get my entity objects to update correctly when using UpdateModel().
I just don't see this as a complex data model. It seems like this should be a very common situation. Perhaps there is something I need to add in the context for the fluent api to elminate this error, but I can't figure it out for the life of me.
ERROR MESSAGE
The operation failed: The relationship could not be changed because one or more of the foreign-key properties is non-nullable. When a change is made to a relationship, the related foreign-key property is set to a null value. If the foreign-key does not support null values, a new relationship must be defined, the foreign-key property must be assigned another non-null value, or the unrelated object must be deleted.
Here are my models and context:
Contact:
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 Conta开发者_如何学PythonctInformationId { 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; }
}
Contact Controller.
public ActionResult Edit(int id, Contact form) {
var contact = db.Contacts.SingleOrDefault(c => c.ContactId == id);
UpdateModel(contact);
db.SaveChanges();
return RedirectToAction("Index");
}
FORM DATA
[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"
UPDATE related issue with some interesting details to my problem Here
Relationships in EF are first-class entities. So when you break this connection you must (1) remove the relationship and (2) delete the entity. In this code:
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));
}
... you do (1) but not (2).
You could do:
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
}
However, the more common way is to put a cascade on the FK and surface that in your model. In which case (1) will work by itself.
精彩评论