2

我試圖用實體框架將實體插入到我的數據庫中。見下:實體框架中的InnerException當我嘗試添加實體

private void InsertarIntoDataBase() 
{ 

    Juego game = db.games.First(g => g.Id == anId); 
    Day d = new Day { 
         DayNumber = this.Number, 
         Game = game // This is a relationship. One Day has one game 
        }; 
    db.AddToDay(d); 
    db.SaveChanges(); 
} 

這總是爲插入,而不是更新。我第一次運行我的應用程序,它工作,然後停止工作,拋出這個異常An error occurred while updating the entries. See the InnerException for details.。 (我確信我沒有改變任何東西)。

爲什麼框架認爲我正在更新?我錯了什麼?

回答

4

這並不意味着您正在進行更新,只是意味着發生了SQL錯誤。您需要閱讀內部異常以找出實際的錯誤。從它的外觀來看,它可能與主鍵或外鍵約束有關,即,您正在添加一個項目,並且該主鍵已經在表格中。但是,再次,實際的錯誤會給你更多的細節。

如果您在Visual Studio中運行,它應該自動打破異常,並且可以展開內部異常屬性。如果沒有,你可以放一個try/catch塊並將其記錄到文件或寫入控制檯。 Exception.ToString()也會顯示所有內部異常,因爲SQL錯誤往往會在幾個不同的異常中包含真正的錯誤。

private void InsertarIntoDataBase() 
{ 
    try 
    { 
     Juego game = db.games.First(g => g.Id == anId); 
     Day d = new Day { 
          DayNumber = this.Number, 
          Game = game // This is a relationship. One Day has one game 
         }; 
     db.AddToDay(d); 
     db.SaveChanges(); 
    } 
    catch (Exception e) 
    { 
     Console.WriteLine(e); // or log to file, etc. 
     throw; // re-throw the exception if you want it to continue up the stack 
    } 
} 
+0

你不應該捕獲'System.Exception'。始終抓住一個特定的例外。 –

+0

@DavidAnderson如果您想以特定方式處理該類型的異常,您會捕獲特定的異常。由於提問者不知道他的SaveChanges失敗的原因,我建議捕捉異常並將其記錄在某處以獲得真正的原因。解決簡單問題的簡單方法。 – Despertar

+0

你應該永遠不會捕獲System.Exception,你應該始終讓它傳播堆棧。這些是應該通過調試和測試來處理的錯誤。請參閱此Msdn主題作爲快速參考(http://msdn.microsoft.com/en-us/library/ms229005.aspx)。有無數的資源說明你爲什麼不應該這樣做,包括在這裏。 –

8

SaveChanges將拋出一個System.Data.Entity.Infrastructure.DbUpdateException當更新命令失敗,它封裝了System.Data.UpdateException終於包裝了一個System.Data.SqlClient.SqlException。請注意,根據您使用的實體框架提供程序,內部異常可能不是SqlException,這一點也很重要。

如果你打開這些東西,你可以看到原始的SqlError對象,這些對象爲你提供了關於更新問題的具體細節。

try 
{ 
    db.SaveChanges(); 
} 
catch (DbUpdateException ex) 
{ 
    UpdateException updateException = (UpdateException)ex.InnerException; 
    SqlException sqlException = (SqlException)updateException.InnerException; 

    foreach (SqlError error in sqlException.Errors) 
    { 
     // TODO: Do something with your errors 
    } 
} 

您還可以通過也趕上System.Data.Entity.Validation.DbEntityValidationException,它會顯示您的呼叫SaveChanges期間發生的任何驗證錯誤獲得了很多的權力和控制。默認行爲是在保存時驗證更改。您也可以致電DbContext.GetValidationErrors()預先驗證更改。

+0

這非常有用。謝謝 – NoughT

0

根據Despertar的回答,我可以解決我的問題。 實體框架有一個選項StoreGeneratedPattern。此選項指示需要設置主鍵ID時的行爲。默認情況下,此選項爲「無」,所以如果您需要自動增量,請將選項StoreGeneratedPattern設置爲「身份」。 This是我讀過的鏈接。

0

是......總是確保如果我們的實體有GUID,那麼'StoreGeneratedPattern'必須設置值「身份」。因爲默認情況下,sqlserver不會爲guid列添加值。

它可以從edmx通過選擇實體右鍵單擊屬性選擇guid列集storedGeneratedPattern設置爲標識。

或者通過給代碼本身分配'Guid.newGuid()'值給列。 ex。 product.Id = Guid.newGuid();