2009-07-28 54 views

答えて

10

私は今日、この問題を少し検討し、いくつかの情報源に基づいて、次の解決策が出ている アイデアを。テーブルアダプターの基本クラスを作成して、テーブルアダプター内のすべてのコマンドのタイムアウトを増やすこともできます。既存のコードをあまり書き直さなくても、生成されたテーブルアダプターは何も役立たないため、リフレクションを使用する必要があります。コンストラクタで使用したものを削除してそれを使用したい場合は、パブリック関数でタイムアウトを変更します。

using System; 
using System.Data.SqlClient; 
using System.Reflection; 

namespace CSP 
{ 
    public class TableAdapterBase : System.ComponentModel.Component 
    { 
     public TableAdapterBase() 
     { 
      SetCommandTimeout(GetConnection().ConnectionTimeout); 
     } 

     public void SetCommandTimeout(int Timeout) 
     { 
      foreach (var c in SelectCommand()) 
       c.CommandTimeout = Timeout; 
     } 

     private System.Data.SqlClient.SqlConnection GetConnection() 
     { 
      return GetProperty("Connection") as System.Data.SqlClient.SqlConnection; 
     } 

     private SqlCommand[] SelectCommand() 
     { 
      return GetProperty("CommandCollection") as SqlCommand[]; 
     } 

     private Object GetProperty(String s) 
     { 
      return this.GetType().GetProperty(s, BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance).GetValue(this, null); 
     } 
    } 
} 
1

あなたのデータセットがMySETと呼ばれているとします。
MyTableと
彼らはクラスにプライベートのように定義されているので、あなたが、あなたのクラスでアダプタのようなメンバーにアクセスすることはできませんいくつかのケースでは

MySETTableAdapters.MyTableTableAdapter fAdapter = 
    new MySETTableAdapters.MyTableTableAdapter(); 
fAdapter.Adapter.SelectCommand.CommandTimeout = <fill inyour value here>; 
+0

-1強く型付けされた 'TableAdapter'が' Adapter'プロパティを公開していないので、 'private'です。これは機能しません。したがって、refelction以外の唯一の方法は、 'TableAdapter'の部分クラスを拡張してパブリックにすることです。 –

2

と呼ばれる一つのテーブルがあります。

幸いにも、ウィザードは部分クラスを生成します。つまり、それらを拡張することができます。 [Piebaldによるこのスレッド] [1]で説明したように、selectコマンドでタイムアウトを設定する独自のプロパティを記述することができます。私は実際に自分自身を、これを試していない

partial class FooTableAdapter 
{ 
    /** 
    * <summary> 
    * Set timeout in seconds for Select statements. 
    * </summary> 
    */ 
    public int SelectCommandTimeout 
    { 
    set 
    { 
     for (int n=0; n < _commandCollection.Length; ++n) 
     if (_commandCollection[n] != null) 
      ((System.Data.SqlClient.SqlCommand)_commandCollection[n]) 
      .commandTimeout = value; 
    } 
    } 
} 

注意が、それは実行可能な解決策のように思える:

一般的に、あなたはこれを行うだろう。

+0

ありがとう!私は_commandCollectionがnullだったので、私のためにこれを動作させることができませんでした。私はいくつかの更新を行い、それを別の答えとして掲示しました。 –

9

いくつかの小さな変更を加えれば、CSLのアイデアはうまくいきます。

partial class FooTableAdapter 
{ 
    /** 
    * <summary> 
    * Set timeout in seconds for Select statements. 
    * </summary> 
    */ 
    public int SelectCommandTimeout 
    { 
    set 
    { 
      for (int i = 0; i < this.CommandCollection.Length; i++) 
       if (this.CommandCollection[i] != null) 
       this.CommandCollection[i].CommandTimeout = value; 
    } 
    } 
} 

がそれを使用するには、ちょうど this.FooTableAdapter.CommandTimeout = 60を設定します。 this.FooTableAdapter.Fill()の前のどこか。


あなたはテーブルアダプタの多くにタイムアウトを変更する必要がある場合は、汎用的な拡張メソッドを作成することができ、それがタイムアウトを変更するためにリフレクションを使用しています。

/// <summary> 
/// Set the Select command timeout for a Table Adapter 
/// </summary> 
public static void TableAdapterCommandTimeout<T>(this T TableAdapter, int CommandTimeout) where T : global::System.ComponentModel.Component 
{     
    foreach (var c in typeof(T).GetProperty("CommandCollection", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.GetProperty | System.Reflection.BindingFlags.Instance).GetValue(TableAdapter, null) as System.Data.SqlClient.SqlCommand[]) 
     c.CommandTimeout = CommandTimeout; 
} 

使用法:

this.FooTableAdapter.TableAdapterCommandTimeout(60); 
this.FooTableAdapter.Fill(...); 

これは少し遅いです。誤ったタイプのオブジェクトで使用すると、エラーが発生する可能性があります。 (私が知る限り、それを制限できる「TableAdapter」クラスはありません。)

0

部分クラスを使用する場合は、正しい名前空間を使用してください。おそらく、[データセットの名前] +「TableAdapters'例:。

名前空間MyProject.DataSet1TableAdapters

4

私は私が最終的に回避することができたミッチェルギルマンのソリューションを使用して問題のカップルを持っていました。

まず、正しい名前空間を使用する必要がありました。 xsdデータセットのDesignerファイルに実際には2つの名前空間が含まれていることがわかりました.1つは一般的なデータセット用、もう1つはテーブルアダプタ用です。したがって、最初に注意すべきことは、一般的なデータセットではなく、テーブルアダプタの名前空間を使用する必要があるということです。

第2に、timeoutコマンドが初めて使用されたときにコマンドコレクションが初期化されないことがあります。この問題を回避するには、InitCommandCollectionコマンドを呼び出しました。

だから私は使用に適応ソリューションは、人々に便利です

namespace xxx.xxxTableAdapters 

partial class FooTableAdapter 
{ 
    /** 
    * <summary> 
    * Set timeout in seconds for Select statements. 
    * </summary> 
    */ 
    public int SelectCommandTimeout 
    { 
    set 
    { 
     if (this.CommandCollection == null) 
       this.InitCommandCollection(); 

     for (int i = 0; i < this.CommandCollection.Length; i++) 
      if (this.CommandCollection[i] != null) 
      this.CommandCollection[i].CommandTimeout = value; 
    } 
    } 
} 

希望でした!

0

プロパティフォルダを開き、Settings.settingsを開き、接続文字列のTimeoutプロパティを変更できます。

0

私はこれが好きです。 Fill()またはGetX()関数を右クリックし、メニューからGoto Definationをクリックします。

DATATABLEのソースコードが表示されます。見つけて ;

private global::System.Data.SqlClient.SqlCommand[] _commandCollection; 

dataadapterクラスのコマンドライン。 プライベートに変更します。

これで、_commandCollectionにアクセスでき、すべての属性を変更できます。

ただし、ファイル形式のDESIGNERを追加または変更するときには注意してください。公開者は、システムを自動生成することで再び非公開になります。

そしてまた、あなたが塗りつぶしコールするか、機能取得を完了したときは(InitCommandCollection()

public void InitCommandCollection() {} 

この関数を呼び出す_commandCollecitonをリセットする必要があります。この機能は、AUTOGENでもプライベートである、あなたはまた、国民に変更する必要があります!

例:秒でTableAdapterのと時間を提供することにより、

dsIslemlerTableAdapters.tblIslemlerTableAdapter _t = new dsIslemlerTableAdapters.tblIslemlerTableAdapter(); 

dsIslemler.tblIslemlerDataTable _m = new dsIslemler.tblIslemlerDataTable(); 

_t._commandCollection[0].CommandText = "Select * From tblIslemler Where IslemTarihi>='' And IslemTarihi<=''"; 

_m = _t.GetData(); 

_t.InitCommandCollection(); 
1

コールChangeTimeout機能。

this.ChangeTimeout(this.taTest, 500); 

機能:

private void ChangeTimeout(Component component, int timeout) 
{ 
    if (!component.GetType().FullName.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; 
    } 

    Interaction.command(0).CommandTimeout = timeout; 
} 
+0

インタラクションとは –

0

ここでVBを使用して、MSDNからいくつかのサンプルコードです。NET:

Imports System.Data.SqlClient 
Namespace MyDataSetTableAdapters 
    Partial Class CustomersTableAdapter 
     Public Sub SetCommandTimeOut(ByVal timeOut As Integer) 
      For Each command As SqlCommand In Me.CommandCollection 
       command.CommandTimeout = timeOut 
      Next 
     End Sub 
    End Class 
End Namespace 

それが長いクエリを呼び出すための時間が来るとき、ちょうどクエリの前にSetCommandTimeOutメソッドを呼び出します。

Dim ds As New MyDataSet 
Dim customersTA As New MyDataSetTableAdapters.CustomersTableAdapter 
' Increase time-out to 60 seconds 
customersTA.SetCommandTimeOut(60000) 
' Do the slow query 
customersTA.FillSlowQuery(ds.Customers) 
0

この1つは、今少し古いですし、このソリューションを疑うことには関係ありません誰もが、私は次のようにObjectDataSourceコントロールを無効にするためにAniPol'sソリューションを使用して終了しました:

helpe tableadaptersため、すでに非常に便利な答えに拡大
public class MyObjectDataSource : ObjectDataSource 
{ 
    public MyObjectDataSource() 
    { 
     this.ObjectCreated += this.MyObjectDataSource_ObjectCreated; 
    } 

    private void MyObjectDataSource_ObjectCreated(object sender, ObjectDataSourceEventArgs e) 
    { 
     var objectDataSourceView = sender as ObjectDataSourceView; 
     if (objectDataSourceView != null && objectDataSourceView.TypeName.EndsWith("TableAdapter")) 
     { 
      var adapter = e.ObjectInstance; 

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

      SqlCommand[] commandCollection = adapterProp.GetValue(adapter, null) as SqlCommand[]; 

      if (commandCollection == null) 
      { 
       return; 
      } 

      foreach (System.Data.SqlClient.SqlCommand cmd in commandCollection) 
      { 
       cmd.CommandTimeout = 120; 
      } 
     } 
    } 
} 
0

d me私はまた、実際のタイムアウト値を読み取る必要がありました。したがって:

namespace XTrans.XferTableAdapters 
{ 

    public partial class FooTableAdapter 
    { 
     int? _timeout = null; 

     ///<summary> 
     ///Get or set the current timeout in seconds for Select statements. 
     ///</summary> 
     public int CurrentCommandTimeout 
     { 
      get 
      { 
       int timeout = 0; 

       if (_timeout != null) 
       { 
        timeout = (int)_timeout; 
       } 
       else 
       { 
        for (int i = 0; i < this.CommandCollection.Length; i++) 
         if (this.CommandCollection[i] != null) 
          timeout = this.CommandCollection[i].CommandTimeout; 
       } 
       return timeout; 
      } 

      set 
      { 
       if (this.CommandCollection == null) 
        this.InitCommandCollection(); 

       for (int i = 0; i < this.CommandCollection.Length; i++) 
        if (this.CommandCollection[i] != null) 
        { 
         this.CommandCollection[i].CommandTimeout = value; 
         _timeout = value; 
        } 
      } 

     } 
    } 

} 
0

これを行うより便利な方法があるようです。ここで私が見つけたものを簡単に要約します。

私のソリューションにMyDBというプロジェクト(クラスライブラリ)を追加してみましょう。そのプロジェクトに「データ」という名前のデータセットを追加します。そのデータセットに「X」というテーブルをドラッグします。

私が「XTableAdapter」というオブジェクトを持っていることを示すオブジェクトがデザインサーフェスに表示されます。

ここで、生成されたコードData.Designer.csを開いて、XTableAdapterを探します。 私はそれが名前空間MyDB.DataTableAdaptersに含まれていることに気付きました。これは、プロジェクトの名前「MyDB」、DataSetの名前、「Data」、および「TableAdapters」を連結したものです。

これを手に入れて、今度はClass1.csと呼ばれるクラスライブラリに戻ります(これは現在無視されます)。

名前空間をMyDBからMyDB.DataTableAdaptersに変更しました。

私は公共部分クラスXTableAdapter、 にクラス宣言を変更すると、それは次のようになります

using System.Data.SqlClient; 

namespace MyDB.DataTableAdapters 
{ 
    public partial class XTableAdapter 
    { 
     public void SetTimeout(int seconds) 
     { 
      foreach (SqlCommand cmd in CommandCollection) 
      { 
       cmd.CommandTimeout = seconds; 
      } 
     } 
    } 
} 

呼び出しシーケンスはほとんど明確にすることができなかった:

int TwoMinutes = 120;  
XTableAdapter.SetTimeout(TwoMinutes); 

少ないMUSS、ほほえり、反射が少ない(うーん、なし)、充填が少ない。

関連する問題