![](/img/trans.png)
[英]ASP.NET MVC 5 application - Repository pattern without Entity Framework
[英]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.