如何更改表适配器的命令超时时间?

19

我正在使用带有C#的Visual Studio 2008。

我有一个.xsd文件, 其中有一个表适配器。我想要更改表适配器的命令超时时间。

感谢您的帮助。

15个回答

14

通过一些小的修改,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.Fill()之前的某个地方设置this.FooTableAdapter.CommandTimeout = 60;。


如果您需要更改许多表适配器的超时时间,可以创建一个通用扩展方法,并使用反射来更改超时时间。

/// <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”类上的方法。)


它非常好用!感谢您10年前的帖子帮助了我,哈哈。 - Derek Tremblay

11
我今天研究了一下这个问题,并根据一些来源提出了以下解决方案。 我的想法是创建一个基类,让表适配器继承它,从而增加表适配器中所有命令的超时时间,而不必重新编写太多现有的代码。由于生成的表适配器没有继承任何有用的内容,因此必须使用反射。它公开了一个函数来更改超时时间,如果你想删除我在构造函数中使用的东西并使用它,就可以这样做。
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);
        }
    }
}

这个怎么被使用! - Khalid Bin Sarower

9

我使用Mitchell Gilman的解决方案时遇到了几个问题,但最终设法解决了。

首先,我需要确保使用正确的命名空间。我花了一些时间才弄清楚xsd数据集的设计器文件实际上包含两个命名空间,一个用于数据集总体,另一个用于表适配器。因此,第一件事是要注意使用表适配器的命名空间,而不是数据集的命名空间。

其次,当第一次使用超时命令时,命令集合可能并不总是被初始化。为了解决这个问题,如果命令集合未被初始化,我调用了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;
    }
  }
}

希望这对人们有所帮助!

2
在某些情况下,您无法访问类中定义为私有的成员,例如Adapter。幸运的是,向导将会生成部分类,这意味着您可以扩展它们。正如Piebald在[此帖子][1]中所述,您可以编写自己的属性来设置选择命令的超时时间。
通常,您需要执行以下操作:
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;
    }
  }
}

请注意,我自己并没有尝试过这个方法,但它似乎是可行的解决方案。

谢谢!我无法使其正常工作,因为_commandCollection为空。我进行了一些更新并将其发布为另一个答案。 - Mitchell Gilman

1

假设你的数据集名字叫MySET。
其中有一张表格叫MyTable。

MySETTableAdapters.MyTableTableAdapter fAdapter = 
   new MySETTableAdapters.MyTableTableAdapter();
fAdapter.Adapter.SelectCommand.CommandTimeout = <fill inyour value here>;

-1 这是行不通的,因为强类型的 TableAdapter 不会公开 Adapter 属性,它是 private 的。所以除了反射之外,唯一的方法就是扩展 TableAdapter 的部分类使其变为公共的。 - Tim Schmelter

1

这里是来自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)

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

什么是交互? - Rudy Hinojosa

1

看起来有更方便的方法来完成这个任务。以下是我找到的快速总结。

假设我在解决方案中添加了一个名为MyDB的(类库)项目。我在该项目中添加了一个名为“Data”的DataSet,并在该数据集中拖动了一个名为“X”的表。

在设计界面上,我得到了一个对象,显示我有一个名为“XTableAdapter”的对象。

现在我打开生成的代码Data.Designer.cs,并查找XTableAdapter。当我找到它时,我注意到它包含在MyDB.DataTableAdapters命名空间中——这只是项目名称“MyDB”、数据集名称“Data”和“TableAdapters”的连接。

有了这个信息,我现在回到仍然称为Class1.cs的类库(我现在将其忽略)。

我将它的命名空间从MyDB更改为MyDB.DataTableAdapters。

我更改了类声明为public partial class 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);

较少的混乱,较少的麻烦,较少的反思(好吧,没有),较少的填充。

0
你可以打开 Properties 文件夹,打开 Settings.settings 并更改连接字符串的 Timeout 属性。

0
如果您使用部分类,请确保您有正确的命名空间。可能是 [您的数据集名称] + "TableAdapters"。例如:
命名空间 MyProject.DataSet1TableAdapters

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接