API调用获取记录后更新数据的最佳方法

时间:2017-02-28 17:23:05

标签: c# rest asp.net-web-api entity-framework-core

我目前正在开发一个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转换为实际数据时,该字段已经改变并且它不会提取任何结果,但是控制器似乎是错误的地方。对数据库进行这种修改。

2 个答案:

答案 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,以获得您启动的句柄值。

相关问题