2013-10-11 116 views
1

下面的ActionResult用於工作,但最近停止工作。 db.SaveChanges()引發例外,抱怨需要UserClass字段。但他們已經在那裏了!如果我只是設置UserClass的價值觀已經有...SaveChanges()異常,抱怨缺少已存在的字段

  item.User = item.User; 
      item.Class = item.Class; 

然後異常消失。顯然這裏有一些我誤解的東西。如果這段代碼失敗了,我該如何更新記錄的字段?

感謝您的見解!

public ActionResult ApproveChange(int id) 
    { 
     var item = db.EnrollmentItems.FirstOrDefault(x => x.ID == id); 

     if (item != null 
      && item.State == EnrollmentState.Submitted 
      && LoginUser.IsManager(ClientBusiness)) 
     { 
      item.State = EnrollmentState.Approved; 
      item.LastTouch = DateTime.UtcNow; 
      db.SaveChanges(); 
      return Json(new { State = item.State }); 
     } 
     return Json(new { State = "error" }); 
    } 

這裏的類定義

public class EnrollmentItem 
{ 
    public int ID { get; set; } 
    [Required] 
    public virtual User User { get; set; } 
    [Required] 
    public virtual Class Class { get; set; } 
    public string Action { get; set; } 
    public string State { get; set; } 
    public DateTime LastTouch { get; set; } 

    public override string ToString() 
    { 
     return 
      String.Format("{0} {1} {2} {3} {4}", 
      User, Action, ID, State, Class); 
    } 
} 

回答

0

因爲實體框架拒絕去數據庫與缺少必需的屬性模型您收到此錯誤。它是空的,因爲你從未從數據庫中獲取它。

通過將它們設置爲自己,您可以調用get方法+ set方法,這將觸發延遲加載,從數據庫中獲取用戶和類對象。
要做到這一點,直接就可以在您的通話firstOrDefault這2個屬性是這樣的:

var item = db.EnrollmentItems 
       .Include(x=>x.User) 
       .Include(x=>x.Class) 
       .FirstOrDefault(x => x.ID == id); 

如果你不想將它們包括我猜你也可以在模型上添加外鍵屬性,以便你不必加入表格。您的類看起來這像當年:

public class EnrollmentItem 
{ 
    public int ID { get; set; } 

    public virtual User User { get; set; } 
    public int UserId{get;set;} 
    public virtual Class Class { get; set; } 
    public int ClassId{get;set;} 
    public string Action { get; set; } 
    public string State { get; set; } 
    public DateTime LastTouch { get; set; } 

    public override string ToString() 
    { 
     return 
      String.Format("{0} {1} {2} {3} {4}", 
      User, Action, ID, State, Class); 
    } 
} 

你必須指定所需的測繪類,但那麼你就可以更新和插入在任一虛擬財產或foreignkeyId(實體框架將弄清楚1方式或另一種)。

+0

這看起來像EF中的一個缺陷......它應該只檢查這個東西,如果我創建一個新的記錄,而不是更新現有的。這個操作應該變成UPDATE Table SET Field = value WHERE ID = id,不需要連接表並檢索更多的行。內置於數據庫中的參照完整性可確保現有的用戶和類字段有效。 EF在實施過程中將我隔離並強制執行額外的工作做得很差。確定咆哮。 最後,我應該在哪裏瞭解到這一點?假設還有其他的EF技巧正在進行,有什麼我應該閱讀? –

+0

說這些字段已經存在的原因是否是正確的,因爲調試器調用了'item.ToString()'來檢索它們?實際上,它必須在項目的副本上調用ToString(),因爲當我通過時db.SaveChanges()仍然拋出異常。 –

+1

對不起,延遲了幾次。如果您調試或調用ToString,則您的懶加載將爲您獲取它。不知道他是否克隆了對象,或者是否實際加載了對象。關於你的咆哮:你根據需要指定了這些屬性,但在你的單元工作(上下文)中你沒有將它們加載到內存中。 EF不能完全依賴於參照完整性,因爲您的上下文和數據庫方案可能會有所不同。至於閱讀材料,我不是一個讀者的大,但我懷疑關係的必要屬性並沒有太多的使用(至少我不)。 – Kristof