4

我有一个带有 QueriesTableAdapter 的数据集。为了控制 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 对象?

4

4 回答 4

11

出于某种原因,我的适配器的 .selectcommand 为空,所以我最终不得不通过 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;            
        }
于 2009-08-06T02:20:28.773 回答
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 中,这就是为什么我没有费心将其作为扩展方法的原因。

于 2009-06-10T14:45:17.367 回答
1

BFree 和mark 的类似解决方案与反射配合得很好。下面是我认为会产生更简洁的代码的轻微改进。

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

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

private void ChangeTimeout(Component component, int timeout)

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

public void ChangeTimeout(int timeout)
于 2010-10-08T21:07:16.590 回答
0

我已经尝试了这两个选项并给出了一些问题在第一个答案上,必须为 2ns 答案适配器上的 CommandCollection 对象导入/使用哪个命名空间。SelectCommand 返回空值

于 2009-07-15T12:13:52.853 回答