2011-01-28 61 views
1

我修改的CommandText LINQ到SQL來強制使用NOLOCK,像這樣...修改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()); 

這是一個MVC應用程序,所以DataContext的是在基本控制器,並可能有在此代碼之前已被使用,更重要的是之後。我應該在這個例程中關閉連接嗎?還是根本不?或者只有當我在這裏打開它?


更新:

我現在使用的更普遍的功能(在DataContext類)修改的CommandText,和關閉,如果它是在這裏開幕的連接。開放已經下移到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出現爲止。