2011-01-28 12 views
1

私はそれはMVCアプリケーションですので、DataContextのは、ベースコントローラであり、そして持っていることがあります...linq-to-sqlのcommandtextを変更するときに、接続を終了する必要がありますか?

if (db.Connection.State == System.Data.ConnectionState.Closed) 
    db.Connection.Open(); 

var cmd = db.GetCommand(db.Customers.Where(p => p.ID == 1)); 

cmd.CommandText = cmd.CommandText.Replace("[Customers] AS [t0]", "[Customers] AS [t0] WITH (NOLOCK)"); 

var results = db.Translate(cmd.ExecuteReader()); 

をLINQからSQLへの本のように、NOLOCKを使用するように強制するのCommandTextをを修正していますこのコードの前に使用されています。このルーチンで接続を終了する必要がありますか?それとも全く?それとも私がここでそれを開いた場合のみ?


更新:

私は今のCommandTextを修正するために(DataContextのクラスで)、より一般的な機能を使用して、それがここで開かれた場合、接続を閉じています。そしてopenはExecuteReaderに移動しました。これまでのところ、散発的なデッドロックの問題を軽減しています。結果は、右上から左へと変化する必要はありません。

public List<T> GetWithNolock<T>(IQueryable<T> query) 
    { 
     // to skip nolock, just... 
     // return query.ToList(); 

     List<T> results = null; 

     bool opened = false; 

     try 
     { 
      if (Connection.State == System.Data.ConnectionState.Closed) 
      { 
       Connection.Open(); 

       opened = true; 
      } 

      using (var cmd = GetCommand(query)) 
      { 
       cmd.CommandText = Regex.Replace(cmd.CommandText, @"((from|inner join) \[dbo.*as \[t\d+\])", "$1 with (nolock)", RegexOptions.IgnoreCase); 

       results = Translate<T>(cmd.ExecuteReader()).ToList(); 
      } 
     } 
     finally 
     { 
      if (opened && Connection.State == System.Data.ConnectionState.Open) 
      { 
       Connection.Close(); 
      } 
     } 

     return results; 
    } 

私はこれまで、推奨される方法でトランザクションを使用すると、サイトの接続が一晩中不足することが判明しました。私の知る限り、これはlinq-to-SQLのバグです。その周りには方法があるかもしれませんが、私はメインコードを簡単に保つよう努めています。私は今、 "ちょうど"これを行う必要があります...

var users = GetWithNolock<User>(
    Users 
    .Where(u => my query 
); 

答えて

0

あなたがそれを閉じる必要があります。他のLinqToSql操作はこのパターンと一致します。

私のコードでは、私は無条件に接続を開き、最後に接続を閉じます。誰かが私にオープンな接続を渡すと、それは彼らのせいであり、私はそれらのために閉じてしまいます。

接続のオープンをExecuteReaderの直前まで延期することができます。

関連する問題