CTP5 EF Code First Question

You can find the source code demonstrating this problem @ http://code.google.com/p/contactsctp5/

I have three model objects. Contact, ContactInfo, ContactInfoType. If a contact has many contacts, and each contactinfo is a contactinfotype. Pretty simple. The problem I am facing is when I go on to edit the contact object. I pulled it out of my contact repository. Then I run "UpdateModel (contact)"; and it updates the object with all the values ​​from my form. (monitoring using debugging) When I save the changes, I get the following error:

The operation failed: the relation cannot be changed because one or more properties of the foreign key are nonzero. When a relationship change occurs, the related foreign-key property is null. If the foreign key does not support null values, a new relationship must be defined, a foreign key property must be assigned another non-zero value, or an unrelated object must be deleted.

It seems that after I call the update model, it cancels my links, and that seems to break everything? Any thoughts on how to fix it would be greatly appreciated. Thanks.

Here are my models:

public partial class Contact { public Contact() { this.ContactInformation = new HashSet<ContactInformation>(); } public int ContactId { get; set; } public string FirstName { get; set; } public string LastName { get; set; } public virtual ICollection<ContactInformation> ContactInformation { get; set; } } public partial class ContactInformation { public int ContactInformationId { get; set; } public int ContactId { get; set; } public int ContactInfoTypeId { get; set; } public string Information { get; set; } public virtual Contact Contact { get; set; } public virtual ContactInfoType ContactInfoType { get; set; } } public partial class ContactInfoType { public ContactInfoType() { this.ContactInformation = new HashSet<ContactInformation>(); } public int ContactInfoTypeId { get; set; } public string Type { get; set; } public virtual ICollection<ContactInformation> ContactInformation { get; set; } } 

My Controller Action:

 [AcceptVerbs(HttpVerbs.Post)] public ActionResult Edit(Contact person) { if (this.ModelState.IsValid) { var contact = this.contactRepository.GetById(person.ContactId); UpdateModel(contact); this.contactRepository.Save(); TempData["message"] = "Contact Saved."; return PartialView("Details", contact); } else { return PartialView(person); } } 

Context Code:

 protected override void OnModelCreating(System.Data.Entity.ModelConfiguration.ModelBuilder modelBuilder) { modelBuilder.Entity<Contact>() .HasMany(c => c.ContactInformation) .WithRequired() .HasForeignKey(c => c.ContactId); modelBuilder.Entity<ContactInfoType>() .HasMany(c => c.ContactInformation) .WithRequired() .HasForeignKey(c => c.ContactInfoTypeId); } 
+6
c # asp.net-mvc entity-framework
source share
2 answers

I understood this question thanks to Mortez Manawi on the entity structure website. My problem was caused by my ContactInformation model properties, the "contactid" and "contacttypeid" were not nullified. Once I fixed this, everything with UpdateModel () worked correctly. Thank you very much!

+1
source share

Here are a few things going on.

1 If you are configured for lazy loading, child objects are loaded only if you tell them to load. This can be done using the following in your request.

..

 context.Contacts.Include(c => c.ContactInfos).Include(c => c.ContactInfos.ContactInfoType) 

see this article for full details on how objects are loaded as you like.

2 If you do not want to save contactinfo and contactinfotype (because they are not loaded or you just do not want to), you will need to tell the context not to save child objects that should not be updated. This can be done using:

..

 context.StateManager.ChangeObjectState(entity.ContactInfos.ContactInfoType, EntityState.Unchanged); 

I find that I need to do this when changing / using a country object for user data. I definitely do not want this to be updated by the user.

In the middle of writing a bit of guidance on all of this, but it may be weeks until this is done on my blog.

3 MVC will not store / send back everything that you do not put on the form. If you submit a hierarchy object to a form and the values ​​are not represented in hidden entries, they are returned to your model empty. For this reason, I generally do viewmodels that are edited only by versions of objects with ToEntity and the ToModel method. It also covers me for security, because I don’t want all kinds of user IDs to be in hidden inputs, so that my entities are displayed directly in MVC (see this article on surge ).

I would think that you have your contactinfo properties set to virtual, UpdateModel doesn’t mind if they did not exist when returning, but I could have been mistaken since I didn’t try.

+3
source share

All Articles