我目前正在开发一个API,其中只允许拉一次记录。它基本上是一个队列,一旦客户端拉出记录,记录上的Retrieved字段就会标记为true。 Get calls仅拉取Retrieved字段为false的记录。
控制器:
[HttpGet]
public virtual IActionResult GetAll([FromQuery] int? limit)
{
try
{
return Ok(_repository.Get(limit));
}
catch
{
return new StatusCodeResult(StatusCodes.Status500InternalServerError);
}
}
存储库:
public IQueryable<Report> Get(int? limit)
{
IQueryable<Report> reports;
if (limit == null)
{
reports = _context.Reports.Where(r => r.Retrieved == false);
}
else
{
reports = _context.Reports.Where(r => r.Retrieved == false).Take((int)limit);
}
return reports;
}
修改Get调用所记录的记录的最佳方法是什么?如果我在从存储库代码返回结果之前进行修改,那么当控制器实际上将IQueryable转换为实际数据时,该字段已经改变并且它不会提取任何结果,但是控制器似乎是错误的地方。对数据库进行这种修改。
答案 0 :(得分:3)
我会将此功能从检索中分离出来。让呼叫者/客户端指示已成功检索报告并通过第二次呼叫读取。这是一个更多的开销,但它增加了弹性。示例:如果服务器调用后检索失败(可能在浏览器或客户端应用程序的网络中),则客户端有另一个机会来检索数据。
控制器:
[HttpPut]
public virtual async Task<IActionResult> MarkAsRetrieved(IEnumerable<int> reportIds, CancellationToken token)
{
await _repository.MarkRetrievedAsync(reportIds, token).ConfigureAwait(true);
return Ok();
}
存储库:
public Task MarkRetrievedAsync([FromBody]IEnumerable<int> reportIds, CancellationToken token)
{
foreach (Report report in reportIds.Select(x => new Report{ReportId = x, Retrieved = false}))
{
_context.Reports.Attach(report);
report.Retrieved = true;
}
return _context.SaveChangesAsync(token);
}
Report
实例的标识符。然后,您可以附加具有相同标识符的空实例,并将Retrieved
属性更新为true
,只需将其发送到相应的商店update
语句中。答案 1 :(得分:0)
我会将数据库中的Retrieved
位更改为某种句柄 - 将ID或记录ID记录到另一个记录提取或其他唯一值的表中。然后我将确定句柄,更新我将要使用该句柄获取的记录,然后检索与该句柄匹配的记录。如果失败,您可以随时将检索到的句柄设置为NULL,以获得您启动的句柄值。