Dapper 的良好实践
Good practices with 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,using 语句会更好,因为它会 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;
}
它可能会导致某种程度的延迟?或者我处理 Action 的方式是 "Good"?谢谢!
使用 using
块始终是最佳做法。但这可能并不适用于所有情况。当您使用 WebApi 时,如果您的事务分布在多个 类 或方法中,请考虑使用 UnitOfWork。如果您有兴趣,请参考 this 代码示例的答案。
using
只释放实现了IDisposable
的对象;在您的情况下,数据库连接。它不处理请求。
关于你的第二个问题,AsList()
应该是。
关于"Action of the Controller",不好不坏。我看不出有任何延误的理由。
SqlConnection
实际上是基于一个内部连接池,所以当你创建和处理它们时,你会从池中获取并返回到池中,除非没有足够的连接,例如第一个连接。
因此,您应该使用 using
和 SqlConnection
。使用静态变量来保存连接实际上是危险的,因为连接的实例方法不能保证跨多个线程工作。
对于Dapper获取的数据,.AsList()
会强制传输结果。明明是"I want the results in memory"的说法。如果你不使用它,你可能会得到一个 IEnumerable<T>
懒惰地获取每一行。
关于您的控制器,您正在将 Query<T>
的结果转换为 List<T>
。这可能行不通,你应该坚持.AsList()
。另一件事是您实际上并没有在控制器中利用 async
的任何好处。你应该做的是 var res = await db.QueryAsync<T>(...).AsList();
并且最后只是 return response;
,TaskCompletionSource<T>
在那里是多余的。
我是 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,using 语句会更好,因为它会 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;
}
它可能会导致某种程度的延迟?或者我处理 Action 的方式是 "Good"?谢谢!
使用 using
块始终是最佳做法。但这可能并不适用于所有情况。当您使用 WebApi 时,如果您的事务分布在多个 类 或方法中,请考虑使用 UnitOfWork。如果您有兴趣,请参考 this 代码示例的答案。
using
只释放实现了IDisposable
的对象;在您的情况下,数据库连接。它不处理请求。
关于你的第二个问题,AsList()
应该是
关于"Action of the Controller",不好不坏。我看不出有任何延误的理由。
SqlConnection
实际上是基于一个内部连接池,所以当你创建和处理它们时,你会从池中获取并返回到池中,除非没有足够的连接,例如第一个连接。
因此,您应该使用 using
和 SqlConnection
。使用静态变量来保存连接实际上是危险的,因为连接的实例方法不能保证跨多个线程工作。
对于Dapper获取的数据,.AsList()
会强制传输结果。明明是"I want the results in memory"的说法。如果你不使用它,你可能会得到一个 IEnumerable<T>
懒惰地获取每一行。
关于您的控制器,您正在将 Query<T>
的结果转换为 List<T>
。这可能行不通,你应该坚持.AsList()
。另一件事是您实际上并没有在控制器中利用 async
的任何好处。你应该做的是 var res = await db.QueryAsync<T>(...).AsList();
并且最后只是 return response;
,TaskCompletionSource<T>
在那里是多余的。