4

一時テーブルを作成しているときに、一時テーブルがすでに存在することを通知するエラーメッセージが表示されます。一時テーブルはセッションに固有であるため、接続が適切に閉じられていないようです。これは、usingステートメントにあるreturnステートメントと関係があると思います。

私は次のコードを持っています:

using (IDbConnection connection = dbConnectionHandler.CreateConnection())
{
   connection.Open();
   CreateATempTable();
   PopulateTempTable();
   DataSet ds = CallStoredProcThatUsesTempTable();
   return ds;
}

この種のコードをいくつかの場所で使用して、同じ名前の一時テーブルを作成します。

残念ながら、次のエラーが発生しますThere is already an object named '#MyTempTable' in the database

これで、一時テーブルはセッションに固有であることがわかったので、セッションを閉じると消えるはずです。

これを引き起こす可能性があると私が信じている3つのことがあります...

  1. connection.Close()を呼び出す必要があります
  2. usingステートメントの外にreturnステートメントを配置する必要があります
  3. 戻る前に作成した一時テーブルを削除する必要があります

誰かがそれがどれであるか知っていますか?またはそれが私が考えていなかったものなら?

4

9 に答える 9

6

ここで推測していますが、データベース接続プールの設定を確認してください。プーリングをオフにしてみて、それが役立つかどうかを確認してください。

通常、.NETライブラリレベルで接続を閉じる/破棄する場合、実際のデータベースサーバー接続は閉じられません。データプロバイダー内の接続プールに返されるだけで、プログラムが同じパラメーターと資格情報を持つ別の接続を要求したときに再利用されます。開いているトランザクションといくつかの基本的なパラメータを除いて、データベースセッションがプールに戻される前にリセットされることはないと思います。一時テーブルなどのより高価なオブジェクトはそのままにしておきます。

プーリングをオフにすることができます(非常に非効率的です)。または、一時テーブルの存在を確認してから作成し、コンテンツが存在する場合は削除することもできます。または、接続を閉じる前に一時テーブルを削除することもできます。

于 2009-02-25T23:49:31.700 に答える
3

connection.Dispose()(したがってconnection.Close()も)が呼び出されることは間違いありません。

1)と2)を実行し、問題がまだ存在することを確認することで、それを簡単に確認できます。解決策はおそらく3)であり、説明は接続プールです。

于 2009-02-25T23:32:43.380 に答える
1

電源の入れ直しが発生しない限り、または他の非常に奇妙なコーナーケースの処分が呼び出されます。

証明が必要な場合は、オブジェクトをラップしてブレークポイントをに入れます。

于 2009-02-25T23:30:25.633 に答える
1

usingブロックは、内部でtry / catch/finallyブロックに変換されます。はい、usingブロック内のリターンに関係なく破棄されます。

于 2009-02-25T23:32:34.363 に答える
1

いいえ、connection.Closeは常に呼び出されます。これは、内部で使用すると、それがtry/finallyブロックに入れられるためです。

また、接続プールを検討することもできます。TransactionScopeでコードをラップしてみてください。

于 2009-02-25T23:32:53.333 に答える
0

It's being caused by connection pooling. Wrap what you are doing in a transaction, and roll it back at the end. Or, drop the temp table after populating the ds.

于 2009-02-25T23:56:09.923 に答える
0

使用中のデータベース接続ライブラリについて詳しく知らなければ、最初の2つではないと思います。usingメソッドから戻るときにそのようなリソースを簡単にクリーンアップできるようにするために特に導入されました。try...finallyこれは、Javaなどの通常のブロックに直接類似しています。

言い換えると、returnはブロックを離れ、Disposeメソッドは接続で呼び出されます。これは、そのような適切な実装を前提としてClose、そのプロセスの一部としてメソッドを呼び出す必要があります。

ここで重要なのは「健全な実装」です。

于 2009-02-25T23:32:20.307 に答える
0

あなたの質問に答えるには:

  1. usingステートメントは、接続のDisposeメソッドが呼び出されると、暗黙的に接続を閉じます。
  2. それは必要ないはずです:http://aspadvice.com/blogs/name/archive/2008/05/22/Return-Within-a-C_2300_-Using-Statement.aspx
  3. それを試してみてください。
于 2009-02-25T23:33:20.180 に答える
0

using ステートメントは、そのクラスが IDisposable の場合、using ブロック内に return ステートメントがあってもオブジェクトを破棄します。

#temptable を保持するのは接続プーリングです。そのテーブルを手動で削除することをお勧めします。

于 2009-02-25T23:41:30.567 に答える