![](/img/trans.png)
[英]Can I use EF Core 2.0 'AsNoTracking' in CRUD service GetAll?
[英]How to use AsNoTracking in a service layer
當我不打算寫任何東西時,我通常使用 AsNoTracking。 我應該如何在 dbContext 隱藏在它后面的服務層中處理這個問題? (我將 EF 核心視為存儲庫,因為它是存儲庫)
public class SomeService
{
//...
public SomeEntity GetById(int id)
{
return _dbContext.Find(id);
}
public SomeEntity GetReadonlyById(int id)
{
return _dbContext.SomeEntitities.AsNoTracking().SingleOrDefault(e => e.Id == id);
}
public SomeEntity Update(SomeEntity someEntity)
{
_dbContext.Update(someEntity);
_dbContext.SaveChanges();
}
}
public class SomeController
{
private readonly SomeService _someService;
//....
[HttpGet("{id}")]
public IActionResult Get(int id)
{
var someEntity = _someService.GetReadonlyById(id);
if (someEntity == null)
{
return NotFound();
}
return someEntity;
}
[HttpPut("{id}")]
public IActionResult Modify(int id, SomeEntity modified)
{
var someEntity = _someService.GetById(id);
if (someEntity == null)
{
return NotFound();
}
someEntity.Someproperty = modified.Someproperty;
_someService.Update(someEntity);
return Ok(someEntity);
}
}
有沒有更好的方法來做到這一點?
我還可以如下定義我的服務:
public class SomeService
{
//...
public SomeEntity GetById(int id)
{
return _dbContext.AsNoTracking.SingleOrDefault(e => e.Id == id);
}
public SomeEntity Update(int id, SomeEntity someEntity)
{
var entity = _dbContext.SomeEntities.Find(id);
if (entity == null)
{
return null;
}
entity.Someproperty = someEntity.Someproperty;
_dbContext.Update(entity);
_dbContext.SaveChanges();
return entity;
}
}
public class SomeController
{
private readonly SomeService _someService;
//....
[HttpGet("{id}")]
public IActionResult Get(int id)
{
var someEntity = _someService.GetById(id);
if (someEntity == null)
{
return NotFound();
}
return someEntity;
}
[HttpPut("{id}")]
public IActionResult Modify(int id, SomeEntity modified)
{
var someEntity = _someService.Update(id, modified);
if (someEntity == null)
{
return NotFound();
}
return Ok(someEntity);
}
}
更好的方法是什么?
基本上,這是更常見的問題。
經常出現優化的讀取方式不方便更新場景,方便的讀取方式更新場景對只讀場景有不必要的開銷。 我在這里看到 3 個選項:
GetById
進行讀取和更新。 顯然,它適用於簡單的應用,可能不適用於高負載的應用。AsNoTracking
方法,甚至在存儲庫中使用普通的sql
。 它適用於復雜的應用程序並且需要更多的代碼。 如評論中所述,您的SomeService
看起來像存儲庫。 理想情況下,域服務應該只包含業務邏輯,而不應該將其與AsNoTracking
等基礎設施功能混合。 而存儲庫可以並且應該包含基礎設施功能,如AsNoTracking
、 Include
等。
當結果用於只讀方案時,沒有跟蹤查詢是有用的。 它們執行速度更快,因為無需設置更改跟蹤信息。
您可以將單個查詢交換為不跟蹤:
using (var context = new BloggingContext())
{
var blogs = context.Blogs
.AsNoTracking()
.ToList();
}
您還可以在上下文實例級別更改默認跟蹤行為:
using (var context = new BloggingContext())
{
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var blogs = context.Blogs.ToList();
}
理想情況下,您應該在存儲庫級別管理基礎設施。
這是我的解決方案。 有用。
所有服務的基礎 CLASS
public class ServicesBase
{
protected AppDbContext dbcontext { get; }
public ServicesBase(AppDbContext dbcontext)
{
this.dbcontext = dbcontext;
}
public void AsNoTracking()
{
dbcontext.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
}
public void SaveChanges()
{
dbcontext.SaveChanges();
}
}
在 CONTROLLER 中使用
_masterService.AsNoTracking();
var master = _masterService.GetById(1);
master.WagePerSquareMeter = 21;
_masterService.SaveChanges();
//or dbcontext.SaveChanges(), both of them will ot affect the database.
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.