2011-03-06 106 views
6

你可以找到源代碼演示這個問題@http://code.google.com/p/contactsctp5/CTP5 EF代碼優先問題

我有三個模型對象。聯繫,的ContactInfo,ContactInfoType。如果聯繫人有多個contactinfo,並且每個contactinfo都是contactinfotype。很簡單,我猜。我遇到的問題是當我去編輯聯繫人對象時。我從我的聯繫人存儲庫中取出它。然後我運行「UpdateModel(contact);」並用我的表單中的所有值更新對象。 (與調試監控)當我保存更改,雖然,我得到以下錯誤:

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.

好像在我稱之爲更新模型,可以空值了我的引用,這似乎打破一切嗎?任何想法如何補救將不勝感激。謝謝。

這裏是我的模型:

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; } 
    } 

我的控制器操作:

[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); 
    } 
+0

錯誤與您在表單上進行的更改類型無關嗎?我可以想象,如果您從Contact中的集合中刪除「ContactInformation」,就會發生這樣的錯誤。如果你只改變表單上的'FirstName'而沒有其他的事情發生,錯誤也會發生嗎? – Slauma 2011-03-06 15:48:19

回答

1

感謝Morteza Manavi在實體框架網站上提出這個問題。我的問題是由我的ContactInformation模型屬性引起的,'contactid'&'contacttypeid'不可爲空。一旦我解決這個問題,UpdateModel()就可以正常工作。非常感謝你!

3

有幾件事會在這裏。

如果您設置爲延遲加載,則只有在您加載子對象時纔會加載子對象。這可以通過查詢中的以下內容來完成。

..

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

看到this article對確保對象的全部細節,只要你想被加載。

如果你不希望保存CONTACTINFO和contactinfotype(因爲它們沒有加載,或者你只是不想),您將需要告訴上下文不救子對象不應該被更新。這是可以做到用:

..

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

我發現我需要改變時/使用國家對象的用戶數據做。我絕對不希望被用戶更新。

在寫一點指導這一切的中間,但直到它在做可能是幾個星期我blog

MVC不會存儲/發回任何你不投入表格。如果您向對象發送一個對象heirarchy,並且這些值不在隱藏輸入中顯示,則它們將在您的模型中返回空。出於這個原因,我通常會製作視圖模型,這些視圖模型只能使用ToEntity和ToModel方法對其進行編輯。這也涵蓋了我的安全性,因爲我不想在隱藏輸入中使用各種用戶標識符,只是讓我的實體直接映射到MVC(請參閱this article on overposting)。

我會認爲你的contactinfo屬性設置爲虛擬,UpdateModel不會介意它們是否在返回時不存在,但我可能錯了,因爲我沒有嘗試過。

+0

我的contactinfo和contactinfotype屬性被標記爲虛擬。我從上下文中獲取我的聯繫對象,通過一個簡單的context.Contact.SingleOrDefault(c => c.ContactId == id); – 2011-03-06 13:29:02

+0

好的,重讀我的答案,現在有點歪斜了。你有沒有嘗試明確包括?我通常在我的倉庫GetQuery方法中添加一個默認的加載級別。它看起來像我第一點中的例子。更改yuour context.Contact.SingleOrDefault(c => c.ContactId == id)到context.Contact.Include(c => c.ContactInfos).SingleOrDefault(c => c.ContactId == id) – Gats 2011-03-06 15:45:11

+0

我嘗試添加包括,但這並沒有改變任何東西,我仍然得到相同的錯誤。表單中的所有值都正確地映射到person變量,並且在調試時一切看起來都很好。但是,當我preform updatemodel()它似乎空參考,當我保存它失敗。 – 2011-03-06 17:33:55