TableAdapterをpartialで拡張する
TableAdapterのDispose問題やストアドプロシージャのリターン値取得・コマンドタイムアウトの、
設定を一気に解決する為にMnow.Data.DAHelperを作成しました。
ソリューションエクスプローラでSampleDataSet.xsdを選択してコードを表示すると、
partialクラスがSampleDataSet.csと言う名前で出来ます。
そこに以下のコードを作成して使います。
namespace Sample.SampleDataSetTableAdapters
{
partial class SampleTableAdapter
{
protected override void Dispose(bool disposing)
{
if (disposing)
{
Mnow.Data.DAHelper.Dispose(this.Adapter, this.Connection, this.CommandCollection);
}
base.Dispose(disposing);
}
public int? GetRerunValue(string procName)
{
return Mnow.Data.DAHelper.GetReturnValue(this.CommandCollection, procName);
}
public int? GetSelectRerunValue()
{
return Mnow.Data.DAHelper.GetReturnValue(this.Adapter.SelectCommand);
}
public int? GetInsertRerunValue()
{
return Mnow.Data.DAHelper.GetReturnValue(this.Adapter.InsertCommand);
}
public int? GetUpdateRerunValue()
{
return Mnow.Data.DAHelper.GetReturnValue(this.Adapter.UpdateCommand);
}
public int? GetDeleteRerunValue()
{
return Mnow.Data.DAHelper.GetReturnValue(this.Adapter.DeleteCommand);
}
public void SetCommandTimeout(string procName, int commandTimeout)
{
Mnow.Data.DAHelper.SetCommandTimeout(this.CommandCollection, procName, commandTimeout);
}
public void SetSelectCommandTimeout(int commandTimeout)
{
Mnow.Data.DAHelper.SetCommandTimeout(this.Adapter.SelectCommand, commandTimeout);
}
public void SetInsertCommandTimeout(int commandTimeout)
{
Mnow.Data.DAHelper.SetCommandTimeout(this.Adapter.InsertCommand, commandTimeout);
}
public void SetUpdateCommandTimeout(int commandTimeout)
{
Mnow.Data.DAHelper.SetCommandTimeout(this.Adapter.UpdateCommand, commandTimeout);
}
public void SetDeleteCommandTimeout(int commandTimeout)
{
Mnow.Data.DAHelper.SetCommandTimeout(this.Adapter.DeleteCommand, commandTimeout);
}
}
}
使うためには以下のコードを DAHelper.csとして一緒においてください。
using System;
using System.ComponentModel;
using System.Data;
using System.Data.SqlClient;
namespace Mnow.Data
{
/// <summary>
/// DataAccess Helperです。
/// DataSetやTableAdapterの補助をします。
/// </summary>
public static class DAHelper
{
#region AddToContainer
/// <summary>
/// TableAdapterをFormのContainerに参加させます。
/// </summary>
/// <param name="container">Formのcontainer ComponentModel.IContainer</param>
/// <param name="component">目的のTableAdapter ComponentModel.Component</param>
/// <remarks>
/// VisualStudio2005デザイナの実装で、TableAdapterがComponentなのに
/// DefaultでContainerに参加していないのを参加させます。
/// <example>
/// Formのコンストラクタで以下のように呼び出してください。
/// <code>
/// Mnow.Data.DAHelper.AddToContainer(this.components,this.sampleTableAdapter1);
/// </code>
/// </example>
/// </remarks>
/// <exception cref="System.ArgumentNullException">
/// <paramref name="container"/><c>パラメータがnullのときスローします</c>.
/// <paramref name="component"/><c>パラメータがnullのときスローします</c>.
/// </exception>
public static void AddToContainer(
IContainer container,
Component component)
{
if (container == null) throw new ArgumentNullException("container");
if (component == null) throw new ArgumentNullException("component");
container.Add(component);
}
#endregion
#region Dispose
/// <summary>
/// TableAdapterの資源をDisposeします。
/// </summary>
/// <param name="adapter">TableAdapter内のDataAdpter System.Data.SqlClient.SqlDataAdapter</param>
/// <param name="connection">TableAdapter内のConnection System.Data.SqlClient.SqlConnection</param>
/// <param name="commandCollection">TableAdapter内のクエリのCommandCollection配列 System.Data.SqlClient.SqlCommand</param>
/// <remarks>
/// VisualStudio2005デザイナの実装でで、TableAdapterがDisposeを行なわないので、
/// 資源が解放されない問題を解決します。
/// <example>
/// SampleDataSet.xsd でコードを表示してパーシャルクラスに以下のコードを書きます。
/// <code>
/// namespace SampleDataSetTableAdapters
/// {
/// partial class SampleTableAdapter
/// {
/// protected override void Dispose(bool disposing)
/// {
/// if (disposing)
/// {
/// Mnow.Data.DAHelper.Dispose(this.Adapter, this.Connection, this.CommandCollection);
/// }
/// base.Dispose(disposing);
/// }
/// }
/// }
/// </code>
/// </example>
/// </remarks>
public static void Dispose(
SqlDataAdapter adapter,
SqlConnection connection,
SqlCommand[] commandCollection)
{
if (commandCollection != null)
{
foreach (SqlCommand cmd in commandCollection) cmd.Dispose();
}
if (adapter != null)
{
if (adapter.UpdateCommand != null) adapter.UpdateCommand.Dispose();
if (adapter.InsertCommand != null) adapter.InsertCommand.Dispose();
if (adapter.DeleteCommand != null) adapter.DeleteCommand.Dispose();
if (adapter.SelectCommand != null) adapter.SelectCommand.Dispose();
adapter.Dispose();
}
if (connection != null) connection.Dispose();
}
#endregion
#region GetReturnValue
/// <summary>
/// Command オブジェクトから StoredProcedure の戻り値を取得する
/// </summary>
/// <param name="command">TableAdapter内のクエリのCommand System.Data.SqlClient.SqlCommand</param>
/// <returns>リターン値(リターン値がない場合はnull) int?</returns>
/// <remarks>
/// 指定したSqlCommandの最後に実行したストアドプロシージャの戻り値を返却する
/// <example>
/// SampleDataSet.xsd でコードを表示してパーシャルクラスに以下のコードを書きます。
/// <code>
/// Namespace SampleDataSetTableAdapters
/// {
/// partial class SampleTableAdapter
/// {
/// public int? GetSelectRerunValue()
/// {
/// return Mnow.Data.DAHelper.GetReturnValue(this.Adapter.SelectCommand);
/// }
/// public int? GetInsertRerunValue()
/// {
/// return Mnow.Data.DAHelper.GetReturnValue(this.Adapter.InsertCommand);
/// }
/// public int? GetUpdateRerunValue()
/// {
/// return Mnow.Data.DAHelper.GetReturnValue(this.Adapter.UpdateCommand);
/// }
/// public int? GetDeleteRerunValue()
/// {
/// return Mnow.Data.DAHelper.GetReturnValue(this.Adapter.DeleteCommand);
/// }
/// }
/// }
/// </code>
/// </example>
/// </remarks>
/// <exception cref="System.ArgumentNullException">
/// <paramref name="command"/><c>パラメータがnullのときスローします</c>.
/// </exception>
public static int? GetReturnValue(SqlCommand command)
{
if (command == null) throw new ArgumentNullException("command");
SqlParameter returnparam = null;
foreach (SqlParameter param in command.Parameters)
{
if (param.Direction == ParameterDirection.ReturnValue)
{
returnparam = param;
break;
}
}
if (returnparam == null) return null;
return (int)returnparam.Value;
}
/// <summary>
/// StoredProcedureの戻り値を取得する
/// </summary>
/// <param name="commandCollection">TableAdapter内のクエリのCommandCollection配列 System.Data.SqlClient.SqlCommand</param>
/// <param name="index">commandCollection配列のインデックス int</param>
/// <returns>リターン値(リターン値がない場合はnull) int?</returns>
/// <remarks>
/// 指定したクエリの最後に実行したストアドプロシージャの戻り値を返却する
/// <example>
/// SampleDataSet.xsd でコードを表示してパーシャルクラスに以下のコードを書きます。
/// <code>
/// Namespace SampleDataSetTableAdapters
/// {
/// partial class SampleTableAdapter
/// {
/// public int? GetRerunValue(int index)
/// {
/// return Mnow.Data.DAHelper.GetReturnValue(this.CommandCollection, index);
/// }
/// }
/// }
/// </code>
/// </example>
/// </remarks>
/// <exception cref="System.ArgumentException">
/// <paramref name="index"/><c>指定したインデックスのクエリのパラメータにリターン値がないときスローします</c>.
/// </exception>
/// <exception cref="System.ArgumentOutOfRangeException">
/// <paramref name="index"/><c>指定したインデックスのクエリ配列の範囲外のときスローします</c>.
/// </exception>
/// <exception cref="System.ArgumentNullException">
/// <paramref name="commandCollection"/><c>パラメータがnullのときスローします</c>.
/// </exception>
public static int? GetReturnValue(SqlCommand[] commandCollection, int index)
{
if (commandCollection == null) throw new ArgumentNullException("commandCollection");
if (index < 0) throw new ArgumentOutOfRangeException("index");
if (index >= commandCollection.GetLength(0)) throw new ArgumentOutOfRangeException("index");
return GetReturnValue(commandCollection[index]);
}
/// <summary>
/// StoredProcedureの戻り値を取得する
/// </summary>
/// <param name="commandCollection">TableAdapter内のクエリのCommandCollection配列 System.Data.SqlClient.SqlCommand</param>
/// <param name="sp_name">ストアドプロシージャ名 string</param>
/// <returns>リターン値(リターン値がない場合はnull) int?</returns>
/// <remarks>
/// 指定したクエリの最後に実行したストアドプロシージャの戻り値を返却する
/// <example>
/// SampleDataSet.xsd でコードを表示してパーシャルクラスに以下のコードを書きます。
/// <code>
/// Namespace SampleDataSetTableAdapters
/// {
/// partial class SampleTableAdapter
/// {
/// public int? GetRerunValue(string procName)
/// {
/// return Mnow.Data.DAHelper.GetReturnValue(this.CommandCollection, procName);
/// }
/// }
/// }
/// </code>
/// </example>
/// </remarks>
/// <exception cref="System.ArgumentException">
/// <paramref name="index"/><c>指定したクエリのパラメータにリターン値がないときスローします</c>.
/// </exception>
/// <exception cref="System.ArgumentNullException">
/// <paramref name="commandCollection"/><c>パラメータがnullのときスローします</c>.
/// <paramref name="procName"/><c>パラメータがnullのときスローします</c>.
/// </exception>
public static int? GetReturnValue(SqlCommand[] commandCollection, string procName)
{
if (commandCollection == null) throw new ArgumentNullException("commandCollection");
if (procName == null) throw new ArgumentNullException("procName");
int? returnValue = null;
if (commandCollection != null)
{
procName = procName.ToLower();
foreach (SqlCommand command in commandCollection)
{
if (command.CommandText.ToLower() == procName)
{
return GetReturnValue(command);
}
}
throw new ArgumentException("指定したクエリのパラメータにリターン値がありません。", "procName");
}
return returnValue;
}
#endregion
#region SetCommandTimeout
/// <summary>
/// Command オブジェクトに CommandTimeout を設定する
/// </summary>
/// <param name="command">TableAdapter内のクエリのCommand System.Data.SqlClient.SqlCommand</param>
/// <param name="commandTimeout">コマンドが実行されるまでの待機時間 (秒)。既定値は 30 秒です。 int</param>
/// <remarks>
/// 指定したSqlCommandに CommandTimeout を設定する
/// <example>
/// SampleDataSet.xsd でコードを表示してパーシャルクラスに以下のコードを書きます。
/// <code>
/// Namespace SampleDataSetTableAdapters
/// {
/// partial class SampleTableAdapter
/// {
/// public void SetSelectCommandTimeout(int commandTimeout)
/// {
/// Mnow.Data.DAHelper.SetCommandTimeout(this.Adapter.SelectCommand, commandTimeout);
/// }
/// public void SetInsertCommandTimeout(int commandTimeout)
/// {
/// Mnow.Data.DAHelper.SetCommandTimeout(this.Adapter.InsertCommand, commandTimeout);
/// }
/// public void SetUpdateCommandTimeout(int commandTimeout)
/// {
/// Mnow.Data.DAHelper.SetCommandTimeout(this.Adapter.UpdateCommand, commandTimeout);
/// }
/// public void SetDeleteCommandTimeout(int commandTimeout)
/// {
/// Mnow.Data.DAHelper.SetCommandTimeout(this.Adapter.DeleteCommand, commandTimeout);
/// }
/// }
/// }
/// </code>
/// </example>
/// </remarks>
/// <exception cref="System.ArgumentNullException">
/// <paramref name="command"/><c>パラメータがnullのときスローします</c>.
/// </exception>
public static void SetSelectCommandTimeout(SqlCommand command, int commandTimeout)
{
if (command == null) throw new ArgumentNullException("command");
command.CommandTimeout = commandTimeout;
}
/// <summary>
/// Command オブジェクトに CommandTimeout を設定する
/// </summary>
/// <param name="commandCollection">TableAdapter内のクエリのCommandCollection配列 System.Data.SqlClient.SqlCommand</param>
/// <param name="index">commandCollection配列のインデックス int</param>
/// <param name="commandTimeout">コマンドが実行されるまでの待機時間 (秒)。既定値は 30 秒です。 int</param>
/// <remarks>
/// 指定したクエリに CommandTimeout を設定する
/// <example>
/// SampleDataSet.xsd でコードを表示してパーシャルクラスに以下のコードを書きます。
/// <code>
/// Namespace SampleDataSetTableAdapters
/// {
/// partial class SampleTableAdapter
/// {
/// public void SetCommandTimeout(int index, int commandTimeout)
/// {
/// Mnow.Data.DAHelper.SetCommandTimeout(this.CommandCollection, index, commandTimeout);
/// }
/// }
/// }
/// </code>
/// </example>
/// </remarks>
/// <exception cref="System.ArgumentOutOfRangeException">
/// <paramref name="index"/><c>指定したインデックスのクエリ配列の範囲外のときスローします</c>.
/// </exception>
/// <exception cref="System.ArgumentNullException">
/// <paramref name="commandCollection"/><c>パラメータがnullのときスローします</c>.
/// </exception>
public static void SetCommandTimeout(SqlCommand[] commandCollection, int index, int commandTimeout)
{
if (commandCollection == null) throw new ArgumentNullException("commandCollection");
if (index < 0) throw new ArgumentOutOfRangeException("index");
if (index >= commandCollection.GetLength(0)) throw new ArgumentOutOfRangeException("index");
commandCollection[index].CommandTimeout = commandTimeout;
}
/// <summary>
/// Command オブジェクトに CommandTimeout を設定する
/// </summary>
/// <param name="commandCollection">TableAdapter内のクエリのCommandCollection配列 System.Data.SqlClient.SqlCommand</param>
/// <param name="sp_name">ストアドプロシージャ名 string</param>
/// <param name="commandTimeout">コマンドが実行されるまでの待機時間 (秒)。既定値は 30 秒です。 int</param>
/// <remarks>
/// 指定したクエリに CommandTimeout を設定する
/// <example>
/// SampleDataSet.xsd でコードを表示してパーシャルクラスに以下のコードを書きます。
/// <code>
/// Namespace SampleDataSetTableAdapters
/// {
/// partial class SampleTableAdapter
/// {
/// public void SetCommandTimeout(string procName, int commandTimeout)
/// {
/// Mnow.Data.DAHelper.SetCommandTimeout(this.CommandCollection, procName, commandTimeout);
/// }
/// }
/// }
/// </code>
/// </example>
/// </remarks>
/// <exception cref="System.ArgumentNullException">
/// <paramref name="commandCollection"/><c>パラメータがnullのときスローします</c>.
/// <paramref name="procName"/><c>パラメータがnullのときスローします</c>.
/// </exception>
public static void SetCommandTimeout(SqlCommand[] commandCollection, string procName, int commandTimeout)
{
if (commandCollection == null) throw new ArgumentNullException("commandCollection");
if (procName == null) throw new ArgumentNullException("procName");
if (commandCollection != null)
{
procName = procName.ToLower();
foreach (SqlCommand command in commandCollection)
{
if (command.CommandText.ToLower() == procName)
{
command.CommandTimeout = commandTimeout;
return;
}
}
throw new ArgumentException("指定したクエリのパラメータにリターン値がありません。", "procName");
}
return;
}
#endregion
}
}



