全局控制TableAdapter命令超时

我有一个带有QueriesTableAdapter的DataSet。 为了控制SqlCommand.CommandTimeout,我添加了一个名为QueriesTableAdapter的分部类,其中包含一个名为ChangeTimeout的公共方法。

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设计器中为您命名的。 我遇到的问题是具有唯一名称的TableAdapter。 例如,如果我有一个名为Person的DataTable和一个名为PersonTableAdapter的TableAdaper,我必须像编写QueriesTableAdaper类一样编写PersonTableAdapter分部类。 我有数百个具有唯一TableAdapter名称的DataTable。 我不想为每个人创建一个部分类。 如何以全局方式访问部分类的基础SqlCommand对象?

由于某种原因,我的适配器的.select命令是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; } 

所有生成的TableAdapter都inheritance自Component。 因此,您可以编写一个这样的方法,使用reflection来提取适配器属性:

  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,这就是为什么我不打算把它作为扩展方法。

BFree和Mark的类似解决方案在reflection方面效果很好。 下面是一个细微的改进,我认为产生更整洁的代码。

您还可以更改TableAdapter在DataSet设计器中使用的基类。 您可以将TableAdapter的基类更改为MyTableAdapterBaseClass或类似名称,以提供所需的function。 您可以通过执行“在文件中查找”并替换DataSet的.xsd文件,在所有TableAdapter上快速进行此更改。

而不是带有签名的调用者的BFree方法:

 private void ChangeTimeout(Component component, int timeout) 

然后,您可以在callee TableAdapter的基类上创建一个带签名的方法:

 public void ChangeTimeout(int timeout) 

我已经尝试了两个选项并给出了一些问题On 1st Answer哪个命名空间必须导入/用于2ns上的CommandCollection对象答案adapter.SelectCommand返回null值