您可以在http://code.google.com/p/contactsctp5/中找到演示此问题的源代码。
我有三个模型对象。 Contact,ContactInfo,ContactInfoType。一个联系人有许多contactinfo且每个contactinfo是一个contactinfotype的地方。我猜很简单。我遇到的问题是当我去编辑联系人对象时。我从联系人存储库中提取了它。然后我运行“UpdateModel(contact);”并使用我表单中的所有值更新对象。 (使用调试进行监视)但是,当我保存更改时,出现以下错误:
似乎在我调用更新模型后,它使我的引用无效了,这似乎破坏了所有内容?任何有关如何补救的想法将不胜感激。谢谢。
这是我的模型:
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; }
}
我的 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);
}
}
上下文代码:
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);
}
最佳答案
这里发生了一些事情。
1 如果设置为延迟加载,则仅在告诉对象加载时才加载子对象。可以在查询中执行以下操作。
..
context.Contacts.Include(c => c.ContactInfos).Include(c => c.ContactInfos.ContactInfoType)
有关确保按需加载对象的完整详细信息,请参见this article。
2 如果您不想保存contactinfo和contactinfotype(因为它们没有被加载或者只是不想),您将需要告诉上下文不要保存不应更新的子对象。可以使用以下方法完成:
..
context.StateManager.ChangeObjectState(entity.ContactInfos.ContactInfoType, EntityState.Unchanged);
我发现在将国家对象更改/使用为用户数据时需要这样做。我绝对不希望用户对此进行更新。
在为所有这些编写一些指南的过程中,但可能要等上几周才能在我的blog上完成
3 MVC不会存储/发送任何您未放入表单的内容。如果将对象层次结构发送到表单,并且值未在隐藏的输入中表示,则它们将在模型上恢复为空。出于这个原因,我通常使 View 模型只能是可编辑的实体版本,并在其上带有ToEntity和ToModel方法。这也涵盖了我的安全性,因为我不想在隐藏的输入中使用各种用户ID,只是为了让我的实体直接映射到MVC中(请参阅this article on overposting)。
我本来以为您将contactinfo属性设置为虚拟,所以UpdateModel不会介意它们在返回时是否不存在,但是我很可能会错,因为我还没有尝试过。
关于c# - CTP5 EF代码第一个问题,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/5208674/