您可以在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/

10-10 19:20