为了重复使用相同的DbCommand并且每次我需要在同一个请求中访问数据库时不重新启动新连接,我创建了一个方法来保存DbCommand并在之前实例化时返回它:
public static class InformacionInscripcionesViewModel {
private static NpgsqlConnection _dbConnection;
private static NpgsqlCommand _dbCommand;
private static NpgsqlCommand GetDbCommand() {
InformacionInscripcionesViewModel._dbConnection = InformacionInscripcionesViewModel._dbConnection ?? new NpgsqlConnection("Host=192.168.1.127;Username=siu;Password=123456;Database=guaraniprueba20160816");
if (InformacionInscripcionesViewModel._dbConnection.State == ConnectionState.Closed)
InformacionInscripcionesViewModel._dbConnection.Open();
return InformacionInscripcionesViewModel._dbCommand
?? (InformacionInscripcionesViewModel._dbCommand = new NpgsqlCommand {Connection = InformacionInscripcionesViewModel._dbConnection});
}
}
在模型中使用它的示例:
var dbCommand = InformacionInscripcionesViewModel.GetDbCommand();
dbCommand.CommandText = @"SELECT sga_propuestas.nombre_abreviado AS nombre_carrera, ....";
dbCommand.ExecuteNonQuery();
当我使用它同时向网址发出2个请求时,它会在dbCommand.ExecuteNonQuery();
处抛出一条包含消息An operation is already in progress
的异常。
我该怎么做才能防止这种情况发生?每次使用前DbCommand
是否应该实施?对此有何看法?
{System.InvalidOperationException: An operation is already in progress.
at Npgsql.NpgsqlConnector.StartUserAction(ConnectorState newState)
at Npgsql.NpgsqlCommand.ExecuteNonQueryInternal()
at Npgsql.NpgsqlCommand.ExecuteNonQuery()
at SIUNPAZ.Models.InformacionInscripcionesViewModels.InformacionInscripcionesViewModel.GetTotalesInscripcionesPorMaterias(DateTime fechaDesde, DateTime fechaHasta, String carrera)
at SIUNPAZ.Controllers.InformacionInscripcionesController.PorMaterias(DateTime fechaDesde, DateTime fechaHasta, String carrera)
at lambda_method(Closure , Object , Object[] )
at Microsoft.AspNetCore.Mvc.Internal.ObjectMethodExecutor.Execute(Object target, Object[] parameters)
at Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker.<InvokeActionFilterAsync>d__28.MoveNext()}
答案 0 :(得分:3)
...并且每次我需要在同一请求中访问数据库时都不会设置新连接
与大多数其他ADO.NET实现一样,Npgsql具有连接池,因此只要您Dispose()
连接对象,除非存在同时查询,否则将重用基础连接。不要在你的ad-hoc连接池中修复bug,只需使用给你的那个。
答案 1 :(得分:2)
您不能跨请求共享数据库连接,这实际上是您通过使它们保持静态而执行的操作。在单个请求中为多个命令共享单个连接是可以的,但其生命周期应该与请求的生命周期相关联。首先,您可以移除静态&#39;你的代码应该运行。您可能需要查看IoC容器(Unity,Ninject,StructureMap等)来为您创建连接,并在构造函数中询问它们。大多数都有终身管理器,可以自动将对象范围限定为HTTP请求。
通常认为在ViewModel中使用逻辑是不好的做法。 ViewModels不应该有DbConnections。您应该研究为数据访问提供服务或将数据库代码移动到控制器。