2016-02-01 37 views
0

我有這樣的代碼:EF EntityState.Modified嘗試捕捉問題

try 
{ 
    Member member = database.Members.Where(m=>m.ID=1).FirstOrDefault(); 
    member.Name = "NewMemberName"; 
    database.Entry(member).State = EntityState.Modified; 
    database.SaveChanges(); 
} 
catch (Exception ex) 
{   
    database.Logs.Add(new Log() { Value=ex.ToString() }); 
    database.SaveChanges(); 
} 

而且實體:

[StringLength(5)] 
public string Name { get; set; } 

如果名稱字符串超過5那將是錯誤和捕獲異常,但是當我添加一個日誌然後保存,SaveChange()的異常;仍然存在,我該怎麼辦?(不能改變架構)

+2

如果'的SaveChanges()'拋出一個異常,爲什麼你會希望它片刻之後立即開展工作?不要在'catch'塊中重新嘗試'SaveChanges()'。 – David

+0

抱歉沒有注意到,我想捕捉異常並向數據庫寫入日誌消息,所以我必須在添加日誌之後使用database.SaveChanges()。 – protoss

回答

1

SaveChange();的異常。仍然

好吧,如果這將引發異常:

database.SaveChanges(); 

然後有一個非常好的機會也將拋出一個異常:

database.SaveChanges(); 

基本上,在你的catch塊中,你不應該立即重新嘗試一個毫秒前失敗的操作。相反,登錄失敗和處理異常:

catch (Exception ex) 
{ 
    // DO NOT call SaveChanges() here. 
} 

當然,如果寫入數據庫出現故障,然後登錄到數據庫可能失敗。假設例如連接字符串錯誤或數據庫關閉或超時。你不能記錄。

我建議使用日誌框架(log4net,NLog等)作爲Entity Framework數據訪問層的單獨依賴項。這是一個小小的學習曲線,但最終你會得到一個非常強大的日誌系統,它可以更有效地處理問題。 可以很容易地配置爲登錄到多個地方,所以如果寫入一個錯誤日誌(數據庫)失敗,那麼你仍然有另一個(例如一個文件)。

至少,如果持續數據上下文失敗,則需要登錄到新的數據上下文。否則失敗的部分仍然存在。

結構上的東西更是這樣的:

try 
{ 
    using (var database = new DbContext()) 
    { 
     Member member = database.Members.Where(m=>m.ID=1).FirstOrDefault(); 
     member.Name = "NewMemberName"; 
     database.Entry(member).State = EntityState.Modified; 
     database.SaveChanges(); 
    } 
} 
catch (Exception ex) 
{ 
    using (var database = new DbContext()) 
    { 
     database.Logs.Add(new Log() { Value=ex.ToString() }); 
     database.SaveChanges(); 
    } 
}