linq-to-sqlコマンドテキストを変更するとき、接続を閉じる必要がありますか?

StackOverflow https://stackoverflow.com/questions/4823530

  •  26-10-2019
  •  | 
  •  

質問

このように、linq-to-sqlのコマンドテキストを変更してnolockを使用するように強制します...

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
);
役に立ちましたか?

解決

あなたがそれを開くならば、あなたはそれを閉じるべきです。他のlinqTOSQL操作はこのパターンと一致します。

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

ExecutEReaderの直前まで接続の開くことを遅らせることができます。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top