接続が開いたままであり、最大プールを超えているという私の質問を閉じるために、データベースへの接続に使用される関数を書き直そうとしています。
関数は、自家製のコンパイル済みライブラリ内に存在します。リフレクターを使用すると、コードが次のようになることがわかります。
public SqlProvider([Optional, DefaultParameterValue("")] string StrConnection)
{
string str;
if (StrConnection == "")
{
str = ConfigurationSettings.AppSettings["ConStr"];
}
else
{
str = StrConnection;
}
SqlConnection connection = new SqlConnection(str);
connection.Open();
this.MyCommand = new SqlCommand();
SqlCommand myCommand = this.MyCommand;
myCommand.Connection = connection;
myCommand.CommandType = CommandType.Text;
myCommand = null;
this.MyDataAdapter = new SqlDataAdapter(this.MyCommand);
this.MyCommandBuilder = new SqlCommandBuilder(this.MyDataAdapter);
this.MyDataSet = new DataSet();
}
修正して読もうと思います
public SqlProvider([Optional, DefaultParameterValue("")] string StrConnection)
{
string str;
if (StrConnection == "")
{
str = ConfigurationSettings.AppSettings["ConStr"];
}
else
{
str = StrConnection;
}
using (SqlConnection connection = new SqlConnection(str))
{
connection.Open();
this.MyCommand = new SqlCommand();
SqlCommand myCommand = this.MyCommand;
myCommand.Connection = connection;
myCommand.CommandType = CommandType.Text;
myCommand = null;
this.MyDataAdapter = new SqlDataAdapter(this.MyCommand);
this.MyCommandBuilder = new SqlCommandBuilder(this.MyDataAdapter);
this.MyDataSet = new DataSet();
}
}
そしてdllを再コンパイルします。のインスタンスSQLProvider()
は通常、パブリック クラスの最上位で作成され、そのインスタンスはクラス メンバー内で使用されます (例:
public class Banner
{
DSLibrary.DataProviders.SqlProvider db = new DSLibrary.DataProviders.SqlProvider(Defaults.ConnStr);
public Banner()
{
}
public DataTable GetBannerImages(string bannerLocation,int DeptId)
{
using (DSLibrary.DataProviders.SqlProvider db = new DSLibrary.DataProviders.SqlProvider(Defaults.ConnStr))
{
DataTable dt = new DataTable();
//Add Parameter @BannerLocation for Banner of Specific Location
//Call proc_getBannerImages Stored procedure for Banner Images
db.AddStoredProcParameter("@BannerLocation", SqlDbType.VarChar, ParameterDirection.Input, 100, bannerLocation);
db.AddStoredProcParameter("@DeptId", SqlDbType.Int, ParameterDirection.Input, 0, DeptId);
dt = db.ExecuteStoredProcedure("proc_getBannerImages");
return dt;
}
}
}
私はこれを正しい方法で行っていますか?データが実際に取得される前に、接続が破棄されるようです。また、Visual Studio は、SQLProvider()
暗黙的に変換可能でなければならないことを教えてくれSystem.IDisposable
ます。これを実装するにはどうすればよいでしょうか。
のすべてのメンバーをステートメントでラップしようとclass Banner
しましたusing (DSLibrary.DataProviders.SqlProvider db = new DSLibrary.DataProviders.SqlProvider(Defaults.ConnStr)){}
が、intellisense は「クラス、構造体、またはインターフェイス メンバー宣言で無効なトークン 'using' です」というエラーを表示します。
これについて最善の方法は何ですか?
更新 DSLibrary の調整と再コンパイルを逆アセンブルしようとしましたが、CHris_Lively が言うように、私には何もしていないと思います。問題のインスタンスを、より標準的な形式であると私が受け取るものに変更すると、これまでのところ機能します。
public DataTable GetBannerImages(string bannerLocation,int DeptId)
{
using (SqlConnection conn = new SqlConnection(Defaults.ConnStr))
{
SqlCommand cmd = new SqlCommand("proc_getBannerImages", conn);
cmd.CommandType = CommandType.StoredProcedure;
cmd.Parameters.Add(new SqlParameter("@BannerLocation", bannerLocation));
cmd.Parameters.Add(new SqlParameter("@DeptId", DeptId));
SqlDataAdapter da = new SqlDataAdapter();
da.SelectCommand = cmd;
DataTable dt = new DataTable();
da.Fill(dt);
return dt;
}
}
私はエンタープライズ ライブラリを調べようとしていますが、それが進むべき道のようです。