2013-04-28 50 views
0

我正在使用實體框架將數據保存在N層Wpf應用程序中。我的dbcontext在所有存儲庫之間共享,並且永遠不會丟棄。當我堅持數據時,我將一個對象標記爲已修改,並嘗試保存更改。如果在持久化對象時出現錯誤,則對象仍被標記爲已修改,並且如果用戶中止當前操作,則在保存另一個對象時他將得到相同的錯誤。使用單個dbcontext時發生異常後恢復

我已經在我的DbContext覆蓋的SaveChanges,如果任何錯誤accurs我接受所有的變化(見下面的代碼)解決了這個。所以如果一個錯誤產生了對象,並且所有對象都被標記爲未改變,即使他們沒有持續。

這感覺不對...... 有誰這個解決方案同意嗎? 另一個解決方案是在我的存儲庫中的每個方法中新建dbcontext並立即處理它們。這將使我的存儲庫更加複雜和「noicy」,我也將失去延遲加載數據的能力... 有沒有人對我有不同的解決方案?

//In my repositories 
    public void UpdateObject(Object object) 
    { 
     dbContext.Entry(object).State = EntityState.Modified; 
     dbContext.SaveChanges(); 
    } 

    //In my dbcontext class 
    private ObjectContext ObjectContext() 
    { 
     return (this as IObjectContextAdapter).ObjectContext; 
    } 

    public override int SaveChanges() 
    { 
     try 
     { 
      return base.SaveChanges(); 
     } 
     catch (Exception) 
     { 
      ObjectContext().AcceptAllChanges(); 
      throw; 
     } 
    } 

回答

0

我們的團隊使用了類似的方法如下所示:

庫:

public class StudentRepository 
{ 
    private readonly MyEntities _context; 

    public StudentRepository(MyEntities context) 
    { 
    _context = context; 
    } 

    // Basic CRUD methods etc 
} 

業務邏輯:

public AddStudent(Student student) 
{ 
    using(var context = new MyEntities()) 
    { 
     var studentrepo = new StudentRepository(context); 
     studentrepo.Add(student); 
     context.SaveChanges(); 
    } 
} 

這是一個過於簡單的例子,但應該給你一個理念。爲了減少代碼,我們還爲CRUD方法使用了一個基本的通用存儲庫類。

如果我們正在從事的項目包括一個Web服務,我們實例化的API控制器中的DbContext和覆蓋Dispose方法來擺脫它。

+0

思爲您answear :) 我曾想過你的解決方案,對我來說不能很好地工作。我正在使用TDD和依賴注入。 回購是通過構造函數注入在我的業務邏輯中發送的。有了你的解決方案,我將不得不爲dbcontext建立一個工廠,併爲每個存儲庫建立一個工廠。 這感覺就像過分複雜的業務邏輯和業務邏輯與事關他們...... – Jakob 2013-04-29 09:32:29

+0

在上面的業務邏輯中,dbcontext和存儲庫都可以通過構造函數注入。就像我在回答中提到的,這只是一個簡單的例子。如果您使用關鍵字(如dbcontext作用域生存期)對Google進行了一些研究,則會發現大多數ppl建議使用短期上下文。根據我自己的經驗,我們發現了一個人忘記處理上下文的錯誤,並且它在Web服務上引起了50ms的查詢,需要3.2分鐘才能執行。 – failedprogramming 2013-04-30 22:00:52

0

有這樣一個長期存在的上下文是不是一個好主意。隨着所有實體和變化的跟蹤,它會變得很大並且很慢,併發性相關的問題可能會出現,並且由您的上下文引發的異常可能會影響您的整個應用程序。

http://msdn.microsoft.com/en-us/data/jj729737

另一種解決方案是新的,在我的 repositores每種方法的DbContext和馬上他們的處置。這將使我 倉庫進行更復雜,「noicy」,我也將失去 能力延遲加載數據

在斷開連接的情況下我會創建和工作的每一個請求/單位處置。擔心你的回購變得複雜?那麼不要使用這個額外的抽象層。回購是否真的有必要?你直接使用DbContext獲得什麼?

至於延遲加載,我認爲在斷開連接的n層場景,延遲加載是不是真的合適。您可能應該爲視圖使用所需數據的急切加載,或者使用單獨的方法調用來獲取相關數據。

+0

認爲你的answear :) 爲了清理我的數據庫層是serperate,我不暴露任何東西從實體框架。我只公開poco對象(代碼第一),所以我可以輕鬆地更改我的db層。我在wpf客戶端中使用db層,並計劃在Web應用程序和Web服務中使用它。在後一種情況下,每次請求後很容易處理上下文。 我擔心的是代碼複製和處理上下文和性能。 你仍然認爲你的解決方案對我來說是最好的嗎? 在你發送的鏈接中聲明「可以工作的一個dbcontext」。 – Jakob 2013-04-29 09:23:24

相關問題