开发者

Entity Framework ModelBinding

开发者 https://www.devze.com 2023-03-10 20:28 出处:网络
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'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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号