2016-09-26 45 views
1

同じDbCommandを再利用し、同じ要求でDBにアクセスする必要があるたびに新しい接続を確立しないために、DbCommandを保存して返すメソッドを作成しましたそれが以前にインスタンス化された場合:それはモデルで使用されているかのASP.NetコアNpgsql操作が既に進行中

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

を、私はそれを使用してURLに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()} 

答えて

3

...と私は同じ要求、他のほとんどのADO.NETの実装と同様に

でDBにアクセスする必要があるたびに新しい接続をinstatiatingない、Npgsqlのは、接続プーリング、その限りがありますDispose()接続オブジェクトでは、同時のクエリがない限り、基礎となる接続が再利用されます。アドホック接続プーリングでバグを修正しないでください。あなたに与えられたものを使用してください。

+0

したがって、NpgsqlConnectionまたはNpgsqlCommandを処分すべきですか? – JorgeeFG

+1

確実に接続を廃棄してください。あなたはコマンドの接続プロパティを解除し、その後にそれを設定することができますが、あなたはあまりそれを保存していません(それ自身のコマンドは "light"です)。 'ブロックして自動的に処理させます。 –

2

基本的には静的にすることで、要求間でDB接続を共有することはできません。 1回のリクエストで複数のコマンドを1つの接続で共有することはできますが、その存続期間はリクエストの存続期間に縛られるべきです。まず「静的」を削除すると、コードが実行されます。 IoCコンテナ(Unity、Ninject、StructureMapなど)を参照して接続を作成し、コンストラクタでそれらのコンテナを要求することができます。ほとんどの場合、オブジェクトをHTTPリクエストに自動的にスコープするライフタイムマネージャがあります。

また、通常、ViewModelにロジックを持たせることは悪い習慣と考えられます。 ViewModelにはDbConnectionsがありません。データアクセスのためのサービスの作成、またはDBコードのコントローラへの移動を検討する必要があります。

関連する問題