我有以下代碼(EntityContext.Current是的DbContext):實體框架的SaveChanges 5()不回滾嘗試的事務
try {
Setting s = new Setting
{
id = 1,
user_id = 0
};
EntityContext.Current.Settings.Add(s);
EntityContext.Current.SaveChanges(); //this violates a foreign key constraint and therefore throws an exception
} catch (Exception ex) {
ErrorContext.Log(ex);
}
我期望(按照this answer)是未決的改變會當他們失敗時會被回滾。但是,在我的錯誤記錄方法中,我發現他們沒有。
Error e = new Error
{
message = ex.Message
};
EntityContext.Current.Errors.Add(e);
var pending = ((IObjectContextAdapter)EntityContext.Current).ObjectContext.ObjectStateManager.GetObjectStateEntries(System.Data.EntityState.Added);
//this contains both my new error entity and my old setting entity which shouldn't be here
EntityContext.Current.SaveChanges();
當我的應用程序嘗試記錄錯誤在數據庫中,它也會嘗試(再一次),以保存無效的外鍵約束,然後導致另外的錯誤日誌記錄的失敗的設置。
這是我第一次遇到EF這種行爲。我嘗試在交易中包裝第一個SaveChanges()
,但發生了同樣的問題。
根據this answer我的連接字符串不包含Enlist=false
要麼。我很茫然。這是預期的行爲?我怎樣才能防止這種情況發生?
我看...非常有趣。我想我也可以簡單地刪除catch塊中的那個實體?那樣當我去寫錯誤(使用相同的上下文)時,它將不再嘗試寫入設置? – Mansfield
@Mansfield:是的,你可以分離實體。這個簡單的例子很容易。但假設你有一個更復雜的場景,並且上下文將包含大量實體,其中包括已添加,已刪除,已修改狀態,並且其中一個會導致違反FK約束。在大多數情況下,很難找到catch塊中有問題的實體並從錯誤中恢復。 – Slauma