2009-06-10 21 views
4

私は、QueriesTableAdapterを持つDataSetを持っています。 SqlCommand.CommandTimeoutを制御するために、私はChangeTimeoutというパブリックメソッドを持つQueriesTableAdapterという部分クラスを追加しました。Control TableAdapterコマンドのタイムアウトがグローバルに

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

私が持っているすべてのデータセットには、QueriesTableAdapterがあります。実行する前にCommandTimeoutを設定できます。

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

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

答えて

11

を返している回答/輸入2nsの上CommandCollectionオブジェクト に使用する必要があり、名前空間第一答えにいくつかの問題 を与え、私のアダプターの両方を試してみました.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;    
     } 
+0

優秀!私も同じ問題がありました。あなたのソリューションは機能します。 –

+0

最後の行コマンド[0] .CommandTimeout = timeout;を置き換えました。 TableAdapterで複数のメソッドを処理するには、次のようにします。 foreach(コマンドでSqlCommand sc) { sc.CommandTimeout = timeout; } – riaandelange

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); 

私はあなたが使用しているため、と仮定していますあなたがまだ.NET 2.0に入っている型付きのDataSetだから、私はこれを拡張メソッドにしていないのです。

+0

BFreeを、代わりに署名して、呼び出し元にBFreeのメソッドの

? –

+0

どこでもあなたは本当に欲しいです。理想的には、静的ヘルパークラスを作成し、それをそのクラスの静的メソッドとして追加するのがよいでしょう。 – BFree

+0

メソッドを置く場所の代替オプションは私の答えです。 – Alex

0

私はオプションとadapter.SelectCommandが何らかの理由でNULL値

+0

http://forums.asp.net/t/1447323.aspx –

1

をBFreeマークの同様のソリューションは、反射でうまく機能します。以下は、より洗練されたコードです。

TableAdapterがDataSetデザイナーで使用する基本クラスを変更することもできます。 TableAdapterの基本クラスをMyTableAdapterBaseClassなどに変更して、必要な機能を提供することができます。 'Find in Files'を実行し、DataSetsの.xsdファイルを置き換えることで、すべてのTableAdapterでこの変更をすばやく行うことができます。あなたは、署名と呼び出し先TableAdapterのの、基本クラスのメソッドを作成することができます

private void ChangeTimeout(Component component, int timeout) 

:私は、このメソッドを追加します

public void ChangeTimeout(int timeout) 
関連する問題