2012-05-16 47 views
0

我想我已經閱讀了關於此的每篇文章和堆棧溢出問題,但無法找到解決方案。讓我開始了我的模特在實體框架4.1中更新FK關係

public class Entry 
{ 
    public Entry() 
    { 
     DateEntered = DateTime.Now; 
    } 

    public int Id { get; set; } 
    [Required] 
    public string FirstName { get; set; } 
    [Required] 
    public string LastName { get; set; } 
    [Required] 
    public string Email { get; set; } 
    public string Number { get; set; } 
    public string FbId { get; set; } 
    [ReadOnly(true)] 
    public DateTime DateEntered { get; set; } 
    public string AccessToken { get; set; } 

    //Relationsips 
    public Backgrounds Background { get; set; } 
    public Cars Car { get; set; } 
} 

public class Backgrounds 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string Filename { get; set; } 
} 

public class Cars 
{ 
    public int Id { get; set; } 
    public string Name { get; set; } 
    public string FileName { get; set; } 
} 

現在在我的控制,我更新的條目。像如下

// PUT /api/entries/5 
    public HttpResponseMessage Put(Entry entry) 
    { 
     if(ModelState.IsValid) 
     { 

      _db.Entries.Attach(entry); 
      _db.Entry(entry).State = EntityState.Modified; 
      _db.SaveChanges(); 

      return new HttpResponseMessage(HttpStatusCode.NoContent); 
     } 

     throw new HttpResponseException(HttpStatusCode.BadRequest); 
    } 

我的入門型號得到正確更新,但如果如entry.Background.Name的變化,這將不會被持久化到數據庫中。我的控制器正在接受整個條目模型,包括其關係=>背景和汽車。但是,更改爲關係的任何值都不會更新或反映。任何優雅的解決方案,而不必查詢數據庫然後更新?我不想在更新之前進行任何額外的查詢或查找。

感謝

泰隆

回答

0

您必須手動告訴EF有關的所有變化做對象圖。你告訴EF只是改變入口實例,但你沒有告訴它有關相關實體或關係本身的任何改變。沒有優雅的方法來解決這個問題。你通常有兩種選擇:

  • 你會使用一些DTO的,而不是你的實體和這些DTO的都會有一些標誌像IsDirty - 當您收到的對象圖回到你的控制器,你將DTO的重建實體及其基於狀態的設置在IsDirty。例如,如果客戶端也可以刪除關係,則此解決方案需要進一步擴展。
  • 您將從數據庫查詢對象圖,並將傳入的更改合併到從數據庫檢索的實體中。

有喜歡強迫由Id == 0他們的狀態設置爲修改,並確定新的對象,但又一次,這些解決方案在特定情況下只能工作將更改保存到所有相關對象的某些部分解決方案。

更復雜的discussion關於這個問題。