与Dapper的良好实践

时间:2017-07-28 12:25:10

标签: c# asp.net-web-api dapper

我是Dapper的初学者,我对最佳做法有些怀疑。我的项目是Asp.net WebApi。

打开连接字符串

this线程中,与Controller一样打开了与数据库的连接,但这是一个简单的项目,并不是WebService:

static IDbConnection db = new SqlConnection(ConfigurationManager.ConnectionStrings["SqlServerConnString"].ConnectionString);  

但是我找到了using语句的其他例子:

using (IDbConnection connection = new SqlConnection(stringConnection))
{
    //do something
}

由于这个项目是WebApi,因此使用声明会更好Dispose请求吗?

列出数据

在上面的同一个帖子中显示了如何根据static IDbConnection db属性检索列表:

var res = (List<ShippDetails>)db.Query<ShippDetails>(query, new { id });

或者最好使用.AsList()

var res = connection.Query<ShippDetails>(query, new { id }).AsList();

控制器的行动

对于我的所有行动,它就像:

[Route("FF")]
    [HttpGet]
    public async Task<HttpResponseMessage> get()
    {         
        var response = new HttpResponseMessage();
        int id = 1;

        var res = (List<ShippDetails>)db.Query<ShippDetails>(query, new { id });

        if (res.Count > 0)
        {
            response = Request.CreateResponse(HttpStatusCode.OK, res);
        }
        else
        {
            response = Request.CreateResponse(HttpStatusCode.NoContent);
        }          

        var task = new TaskCompletionSource<HttpResponseMessage>();
        task.SetResult(response);
        return await task.Task;
    }

可能会导致某种延迟?或者我处理我的行动的方式是“好”?谢谢!

2 个答案:

答案 0 :(得分:5)

SqlConnection实际上是基于内部连接池,因此当您创建和处理它们时,除了没有足够的连接外,您将从该池获取并返回该池。第一次联系。

因此,您应该将usingSqlConnection一起使用。使用静态变量来保持连接实际上很危险,因为连接的实例方法不能保证跨多个线程工作。

对于使用Dapper获得的数据,.AsList()将强制传输结果。这是一个明确的声明“我希望结果在记忆中”。如果你不使用它,你可能会得到IEnumerable<T>,懒洋洋地得到每一行。

关于您的控制器,您将结果Query<T>投射到List<T>。这可能不起作用,你应该坚持.AsList()。另一件事是你实际上并没有在控制器中获得async的任何好处。你应该做的是var res = await db.QueryAsync<T>(...).AsList();而最后只是return response;TaskCompletionSource<T>在那里是多余的。

答案 1 :(得分:1)

使用using块始终是最佳做法。但是,这可能不适用于所有情况。在使用WebApi时,如果您的事务分布在多个类或方法中,请考虑使用UnitOfWork。如果您感兴趣,请参阅this答案以获取代码示例。

using仅处理实现IDisposable的对象;在您的情况下,数据库连接。它不会处理请求。

关于第二个问题,AsList()应为good practice

关于“控制者的行动”,这不是好事或坏事。我认为没有任何理由导致任何延误。