ASP.Net核心Npgsql一项操作已在进行中

时间:2016-09-26 16:58:24

标签: c# asp.net asp.net-core npgsql

为了重复使用相同的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()}

2 个答案:

答案 0 :(得分:3)

  

...并且每次我需要在同一请求中访问数据库时都不会设置新连接

与大多数其他ADO.NET实现一样,Npgsql具有连接池,因此只要您Dispose()连接对象,除非存在同时查询,否则将重用基础连接。不要在你的ad-hoc连接池中修复bug,只需使用给你的那个。

答案 1 :(得分:2)

您不能跨请求共享数据库连接,这实际上是您通过使它们保持静态而执行的操作。在单个请求中为多个命令共享单个连接是可以的,但其生命周期应该与请求的生命周期相关联。首先,您可以移除静态&#39;你的代码应该运行。您可能需要查看IoC容器(Unity,Ninject,StructureMap等)来为您创建连接,并在构造函数中询问它们。大多数都有终身管理器,可以自动将对象范围限定为HTTP请求。

通常认为在ViewModel中使用逻辑是不好的做法。 ViewModels不应该有DbConnections。您应该研究为数据访问提供服务或将数据库代码移动到控制器。