2009-06-10 124 views
4

我有一個帶有QueriesTableAdapter的DataSet。爲了控制SqlCommand.CommandTimeout,我用一個名爲ChangeTimeout的公共方法添加了一個名爲QueriesTableAdapter的分類。全局控制TableAdapter命令超時

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

這很好用,因爲「QueriesTableAdapter」是在DataSet設計器中爲您命名的。我遇到的問題是唯一命名的TableAdapters。例如,如果我有一個名爲Person的DataTable和一個名爲PersonTableAdapter的TableAdaper,那麼我必須以編寫QueriesTableAdaper類的相同方式編寫PersonTableAdapter分部類。我有數百個具有唯一TableAdapter名稱的DataTables。我不想爲每個人創建一個部分類。我如何以全局方式訪問部分類的底層SqlCommand對象?

回答

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;    
     } 
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中,這就是爲什麼我不打擾使這個擴展方法。

+0

貝麗,在那裏我會添加這個方法? – 2009-06-10 16:29:43

+0

任何你想要的東西。理想情況下,您可能會創建一個靜態幫助器類,並將其作爲該類中的靜態方法添加。 – BFree 2009-06-10 16:34:48

+0

我的答案是放置方法的替代選項。 – Alex 2010-10-08 21:07:51

0

我已經試過這兩個選項,並給予一定的問題 1日回答其命名空間必須依靠進口/用於在2ns的CommandCollection對象 答案adapter.SelectCommand因某種原因而返回空值

1

貝麗和標記的類似解決方案與反思工作。下面是我認爲會產生更整潔的代碼的細微改進。

您還可以更改TableAdapter在DataSet設計器中使用的基類。你可以改變你的TableAdapter的基類爲MyTableAdapterBaseClass或類似的提供你需要的功能。您可以通過執行「在文件中查找」並替換您的DataSets的.xsd文件,在所有TableAdapter上快速進行此更改。

而不是貝麗的上簽字來電方法:

private void ChangeTimeout(Component component, int timeout) 

然後你可以創建一個簽名就被叫TableAdapter的基類的方法:

public void ChangeTimeout(int timeout)