4

QueriesTableAdapter を含む DataSet があります。SqlCommand.CommandTimeout を制御するために、ChangeTimeout というパブリック メソッドを持つ QueriesTableAdapter という部分クラスを追加しました。

partial class QueriesTableAdapter
{
    public void ChangeTimeout(int timeout)
    {
        foreach (System.Data.SqlClient.SqlCommand cmd in CommandCollection)
        {
            cmd.CommandTimeout = timeout;
        }
    }
}

QueriesTableAdapter を持つすべての DataSet に対して、実行前に CommandTimeout を設定できます。

using (NameSpace.DataSet.DataSetTableAdapters.QueriesTableAdapter ta =
new NameSpace.DataSet.DataSetTableAdapters.QueriesTableAdapter())
{
    ta.ChangeTimeout(3600);
    ta.DoSomething();
}

DataSet デザイナで「QueriesTableAdapter」という名前が付けられているため、これはほとんどの場合うまく機能します。私が直面している問題は、一意に名前が付けられた TableAdapters です。たとえば、Person という名前の DataTable と PersonTableAdapter という名前の TableAdaper がある場合、QueriesTableAdaper クラスを作成したのと同じ方法で PersonTableAdapter 部分クラスを作成する必要があります。一意の TableAdapter 名を持つ何百もの DataTables があります。それらのそれぞれに部分クラスを作成したくありません。部分クラスの基になる SqlCommand オブジェクトにグローバルな方法でアクセスするにはどうすればよいですか?

4

4 に答える 4

11

何らかの理由で、アダプターの .selectcommand が null だったため、代わりに CommandCollection オブジェクトを使用する必要があったため、上記の以前の回答に基づいて小さな変更を投稿すると思いました。

以下が含まれます:

using System.ComponentModel;
using System.Reflection;

コード:

private void ChangeTimeout(Component component, int timeout)
        {
            if (!component.GetType().Name.Contains("TableAdapter"))
            {
                return;
            }

            PropertyInfo adapterProp = component.GetType().GetProperty("CommandCollection", BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance);
            if (adapterProp == null)
            {
                return;
            }           

            SqlCommand[] command = adapterProp.GetValue(component, null) as SqlCommand[];

            if (command == null)
            {
                return;
            }

            command[0].CommandTimeout = timeout;            
        }
于 2009-08-06T02:20:28.773 に答える
3

生成されたすべての TableAdapter は Component から継承します。したがって、リフレクションを使用してアダプタ プロパティを抽出する次のようなメソッドを作成できます。

    private void ChangeTimeout(Component component, int timeout)
    {
        if (!component.GetType().Name.Contains("TableAdapter"))
        {
            return;
        }

        PropertyInfo adapterProp = component.GetType().GetProperty("Adapter", BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance);
        if (adapterProp == null)
        {
            return;
        }

        SqlDataAdapter adapter = adapterProp.GetValue(component, null) as SqlDataAdapter;
        if (adapter == null)
        {
            return;
        }

        adapter.SelectCommand.CommandTimeout = timeout;
    }

次に、次のように呼び出すことができます。

MyTableAdapter ta = new MyTableAdapter();
this.ChangeTimeout(ta,1000);

型指定された DataSet を使用しているため、まだ .NET 2.0 を使用していると想定しているため、これを拡張メソッドにする必要はありませんでした。

于 2009-06-10T14:45:17.367 に答える
1

BFree と mark の同様のソリューションは、リフレクションでうまく機能します。以下は、よりきれいなコードが得られると思われるわずかな改良です。

DataSet デザイナーで TableAdapter が使用する基本クラスを変更することもできます。TableAdapter の基本クラスをMyTableAdapterBaseClassなどに変更して、必要な機能を提供できます。「ファイル内を検索」を実行し、DataSet の .xsd ファイルを置き換えることで、すべての TableAdapter でこの変更をすばやく行うことができます。

署名付きの呼び出し元での BFree のメソッドの代わりに:

private void ChangeTimeout(Component component, int timeout)

その後、署名付きの呼び出し先 TableAdapter の基本クラスでメソッドを作成できます。

public void ChangeTimeout(int timeout)
于 2010-10-08T21:07:16.590 に答える