当我不打算写任何东西时,我通常会使用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);
}
}
更好的方法是什么?
答案 0 :(得分:1)
基本上,这是更常见的问题。
通常情况下,优化的阅读方法不便于更新场景,而更新场景的方便阅读方法对于只读场景具有不必要的开销。我在这里看到3个选项:
GetById
进行读取和更新。显然,它适用于简单的应用,可能不适用于高负载应用。AsNoTracking
方法,甚至可以在存储库中使用普通sql
。它适用于复杂的应用程序,需要更多代码。如评论中所述,您的SomeService
看起来像存储库。理想情况下,域服务应仅包含业务逻辑,不应将其与AsNoTracking
等基础结构功能混合使用。而存储库可以而且应该包含AsNoTracking
,Include
等基础设施功能。
答案 1 :(得分:0)
在只读方案中使用结果时,没有跟踪查询很有用。由于不需要设置更改跟踪信息,因此执行起来更快。
您可以将单个查询交换为不跟踪:
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();
}
理想情况下,您应该在存储库级别管理基础架构。