Web Api控制器:使用Controller自己的方法多次访问数据库?

时间:2015-04-01 12:36:30

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

我正在为我的一个项目写一个NodeController。它链接到一个数据库,并且它的所有方法都获取一个ID,以便在EF数据库中访问哪个Node。 一个节点可以在另一个节点上有一个依赖,这意味着,如果我想说,“执行”一个节点,我必须检查是否已经执行了任何依赖节点,并且失败了,如果不是所有的依赖都已被执行。

我将呈现我的两个方法的部分版本,而另一个使用另一个,但首先,我们的Controller的构造函数,稍后会提到:

private readonly NodeDBContext _context;

public NodeController()
{
    _context = new NodeDBContext();
}

这是使用DbContext的正确方法吗,或者我们是否应该在执行与数据库相关的事情(在我们的情况下为获取或放置)时使用“using”语句?

[ResponseType(typeof(bool))]
[HttpGet]
[Route("node/{id}/executed")]
public async Task<IHttpActionResult> Executed(int id)
{
    var node = await NodeControllerHelper.GetNode(_context, id);
    if (node == null) return BadRequest("There is no such Node");
    return Ok(node.Executed);
}

如您所见,上面的方法使用了一个“_context”,它是一个继承自DbContext的NodeDbContext。我将这个字段化的DbContext传递给将从数据库中检索Node对象的方法是否正确? 下面的方法将使用“NodeControllerHelper.GetNode”方法以及 Executed(int id)方法:

[HttpPut]
[Route("node/{id}/executed")]
public async Task<IHttpActionResult> Executed(int id, PutMessage message)
{
    //Interpret input
    var node = await NodeControllerHelper.GetNode(_context, id);
    if (node == null) return BadRequest("There is no such Node");

    foreach (var condition in node.Conditions)
    {
        bool executed = false;
        response = await Executed(condition.Id).Result.ExecuteAsync(new CancellationToken(false));
        executed = JsonConvert.DeserializeObject<bool>(await response.Content.ReadAsStringAsync());
    if (!executed)
    { // Precondition has not been executed
        await NodeControllerHelper.UnlockNodeIfSelfLockedAndSave(_context, node);
        return BadRequest("One or more preconditions are not currently fulfilled.");
    }
}

可以看出,首先进行.GetNode调用,这意味着在那里有一个对DbContext的调用,并且还有“Executed(condition.Id)”调用,这当然最终调用了.GetNode方法再一次。 这是我们似乎已经触及某种摇滚的地方,因为PUT /执行的方法在超过一半的时间里似乎都失败了,但有时会设法挤出,超出我的理解。

关于如何最好地确保我们的控制器代码的所有级别的幸福,我有一个更普遍的问题;

  • 管理DbContext的最佳做法是什么?目前,它正在控制器的构造函数中实例化,设置为私有只读字段并分散为“更深层次”方法调用。这似乎有些麻烦。调试时,一旦我们到达.GetNode方法的第二次调用,然后我们从数据库的表中调用'get'ting',调试神秘地停止,抛出一些Exception,我们用来调用客户端到Api没有收到任何HttpResponseMessage。另一种方法是使用“using”语句创建自己的短命DbContext,但是我们之前尝试过这个实现,并且它在第二个.GetNode调用时似乎有同样的问题。

以下是GetNode方法,供参考:

public static async Task<Node> GetNode(NodeDBContext context, int id)
{
    var node = await context.Nodes.FindAsync(id);
    return node;
}

该死的,这篇文章比我最初想要呈现的时间更长,尽管也发生了代码切换。我希望那里有人看到我们错误地做了些事情,并且可以纠正我们可能稍微有点根本的实施错误......

提前多多谢谢你, Kirluu

0 个答案:

没有答案