2009-06-10 122 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)