2016-09-26 68 views
1

爲了重複使用相同的DbCommand而不是每次需要在同一個請求中訪問數據庫時創建一個新連接,我創建了一個方法來保存DbCommand並返回如果它以前實例:ASP.Net核心Npgsql操作已在進行中

var dbCommand = InformacionInscripcionesViewModel.GetDbCommand(); 
dbCommand.CommandText = @"SELECT sga_propuestas.nombre_abreviado AS nombre_carrera, ...."; 
dbCommand.ExecuteNonQuery(); 

當我讓使用它的URL 2個同時請求,它拋出一個異常,在dbCommand.ExecuteNonQuery();用:它是如何在模型中使用

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}); 
     } 
} 

例消息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()} 

回答

3

......每次我需要訪問數據庫中同一請求

像大多數其他ADO.NET實現時間不instatiating一個新的連接,具有Npgsql的連接池,因此只要如果連接對象爲Dispose(),則底層連接將被重用,除非存在同時查詢。不要修復特定連接池中的錯誤,只需使用已提供給您的錯誤即可。

+0

所以,我應該處置NpgsqlConnection或NpgsqlCommand? – JorgeeFG

+1

絕對配置連接。雖然你可以取消命令的連接屬性,然後在病房後再次設置它,但你並沒有太多的節省(這個命令本身就是「輕量級」),所以我只是把它們放在'使用'塊,並自動處理。 –

2

您不能通過請求共享數據庫連接,這基本上是通過將它們設置爲靜態的方式實現的。在單個請求中共享多個命令的單個連接是可以的,但其生命週期應與請求的生命週期相關聯。作爲開始,你可以刪除'靜態',你的代碼應該運行。你可能想看一個IoC容器(Unity,Ninject,StructureMap等)來爲你創建連接,並在你的構造函數中請求它們。大多數終端管理員都可以自動將對象範圍限定爲HTTP請求。

另外它通常被認爲是在您的ViewModels邏輯不好的做法。 ViewModels不應該有DbConnections。您應該考慮爲數據訪問提供服務或將DB代碼移動到控制器。