2009-07-28 66 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的部分類來公開它。 – 2014-03-11 15:22:32

2

在某些情況下,你不能訪問成員一樣適配器在類一張表,因爲它們被定義爲私人到類。

幸運的是,嚮導會生成部分類,這意味着您可以擴展它們。如[在Piebald的此線程] [1]中所述,您可以編寫自己的屬性來設置select-commands上的超時值。

一般情況下,你可以這樣做:

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。我做了一些更新併發布了另一個答案。 – 2010-01-20 15:01:15

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;在這之前的某處.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

如果您使用部分類,使您擁有正確的名稱空間。也許[你的數據集的名稱] +「TableAdapter的例:

命名空間MyProject.DataSet1TableAdapters

4

我在使用Mitchell Gilman的解決方案時遇到了一些問題,我終於可以解決問題了。

首先,我需要確保使用正確的命名空間。我花了一段時間才發現xsd數據集的Designer文件實際上包含兩個名稱空間,一個用於數據集,一個用於表適配器。所以首先要注意的是應該使用表適配器的名稱空間,而不是一般的數據集。

其次,當第一次使用超時命令時,可能不會始終初始化commandcollection。要解決這個問題,我會調用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

您可以打開Properties文件夾,打開Settings.settings並更改連接字符串的Timeout屬性。

0

我喜歡這樣;右鍵單擊Fill()GetX()函數,然後從菜單中單擊Goto Defination

你會看到DATATABLE的源代碼。並找到;

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

您的dataadapter類的命令行。 並將私人更改爲公共。

現在你可以訪問_commandCollection,你可以改變所有的屬性。

但是,當您添加或更改任何Filed表單DESIGNER時,請注意,公衆將通過自動生成系統再次隱私。

而且也,當你完成調用填充或獲取函數必須復位_commandColleciton調用這個函數(InitCommandCollection()

public void InitCommandCollection() {} 

此功能也由AUTOGEN私有,你必須改變公衆也!

實施例:

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

呼叫通過提供以秒爲單位的TableAdapter和時間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

什麼是交互? – 2016-11-03 15:37:45

0

下面是MSDN一些示例代碼,用VB。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

這一個是現在有點老懷疑這個解決方案是不相關的每個人,但我已經結束了使用AniPol's解決方案覆蓋ObjectDataSource控件如下:

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

就已經非常有用的答案擴大爲helpe的TableAdapter我很多,我也需要讀出實際的超時值。因此:

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的(類庫)項目。在該項目中,我添加了一個名爲「Data」的DataSet。進入該數據集,我拖動一個名爲「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); 

少搞亂,少些大驚小怪,反射少(好,沒有),少填充。