簡體   English   中英

服務模式實體框架asp.net mvc

[英]Service pattern entity framework asp.net mvc

我想在我的asp.net mvc實體框架6項目中進行單元測試,這迫使我查看我的代碼。 我讓我的控制器暴露在我的背景下,並決定我應該把它分開。 我最初看的是存儲庫/ UoW模式,但在閱讀了很多之后我決定使用DI的簡單服務模式(即,控制器注入了具有GetProducts()FindProduct()等的服務)。

我的問題與此模式中的更改跟蹤有關。 之前我在控制器方法中完成了很多事情之后才調用SaveChanges() ,但是將所有方法分開后會產生如下方法:

 public void AddRequest(Request request)
    {
        using (PricedNotesContext ctxt = new PricedNotesContext())
        {
            ctxt.Requests.Add(request);
            ctxt.SaveChanges();
        }
    }

 public void DeleteRequestData(BaseRequestData reqData)
    {
        using (PricedNotesContext ctxt = new PricedNotesContext())
        {
            ctxt.RequestData.Remove(reqData);
            ctxt.SaveChanges();

        }
    }

在上面你看到SaveChanges()被調用兩次。 但我只想要它一次。 我只希望如果兩個操作都成功完成,我的更改仍會存在。 建議的解決方案是只有一個名為SaveChanges()Dispose() ,它顯然調用暴露給控制器的SaveChanges()Dispose()來管理事務?

謝謝你的幫助!

您的服務應提供功能,使消費者不必關心保存上下文。 實際上,它不了解背景。 你為什么不簡單地做一些事情:

public class EfNotesService : INotesService
{
      public ExecuteSomeBusinessOperation(input parameters here)
      {
            // Validate input parameters

            using (PricedNotesContext ctxt = new PricedNotesContext())
            {
                ctxt.Requests.Add(...);
                ctxt.RequestData.Remove(...);

                // other logic

                ctxt.SaveChanges();
            }
      }
}

或者更好的是,您還可以使用依賴注入在請求開始時注入上下文,並在請求結束時將其處理掉。 然后將此上下文注入到EfNotesService的構造函數中,然后您可以在沒有using語句的情況下使用它:

public class EfNotesService : INotesService
{
      private readonly PricedNotesContext _ctxt;

      public EfNotesService(PricedNotesContext ctxt )
      {
          _ctxt = ctxt;
      }
      public ExecuteSomeBusinessOperation(input parameters here)
      {
            // Validate input parameters

            _ctxt .Requests.Add(...);
            _ctxt .RequestData.Remove(...);

            // other logic

            _ctxt .SaveChanges();               
      }
}

像這樣,相同的上下文可以跨越多個服務,您不必擔心在這些服務中創建和處理上下文。

此外,在您的服務操作中,您當然可以使用業務組件甚至域層來執行業務邏輯,而不是在服務中執行所有操作。

並添加一個全局異常處理程序來優雅地處理異常。

這就是我想出來的。

public class EfNotesService : INotesService
{
    private readonly PricedNotesContext _ctxt = new PricedNotesContext();

    public IEnumerable<Request> GetAllRequests()
    {
        return _ctxt.Requests.ToList();
    }

    public void SaveRequest(Request request)
    {
        _ctxt.Entry(request).State = EntityState.Modified;
    }

    public void DeleteRequestData(BaseRequestData reqData)
    {
        _ctxt.RequestData.Remove(reqData);
    }
    // ...
    // Other methods...
    // ...

    // Transaction control
    public void SaveChanges()
    {
        _ctxt.SaveChanges();
    }

    public void Dispose()
    {
        _ctxt.Dispose();
    }
}

它不是UoW或Repository,但它很簡單,效果很好。 另外,我保留了DbContext的所有“商店”優勢。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM