如何更改表适配器的命令超时
我正在使用Visual Studio 2008和C#。
我有一个.xsd文件,它有一个表适配器。 我想更改表适配器的命令超时。
谢谢你的帮助。
我今天对此问题进行了一些调查,并根据几个来源提出了以下解决方案。 我们的想法是为表适配器创建一个基类inheritance,这会增加表适配器中所有命令的超时,而不必重写太多的现有代码。 它必须使用reflection,因为生成的表适配器不会inheritance任何有用的东西。 如果你想删除我在构造函数中使用的东西并使用它,它会公开一个公共函数来改变超时。
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); } } }
通过一些小的修改,csl的想法很有效。
partial class FooTableAdapter { /** * * Set timeout in seconds for Select statements. * */ 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.CommandTimeout = 60; 在this.FooTableAdapter.Fill()之前的某个地方;
如果需要更改许多表适配器的超时,可以创建一个通用扩展方法并让它使用reflection来更改超时。
/// /// Set the Select command timeout for a Table Adapter /// public static void TableAdapterCommandTimeout(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”类可以限制它。)
我在使用Mitchell Gilman的解决方案时遇到了一些问题,我最终能够解决这个问题。
首先,我需要确保使用正确的命名空间。 我花了一段时间才发现xsd数据集的Designer文件实际上包含两个名称空间,一个用于一般数据集,另一个用于表适配器。 所以首先要注意的是应该使用表适配器的命名空间,而不是一般的数据集。
其次,当第一次使用超时命令时,可能不会始终初始化commandcollection。 为了解决这个问题,我调用了InitCommandCollection命令(如果是这种情况)。
所以我使用的改编解决方案是
namespace xxx.xxxTableAdapters partial class FooTableAdapter { /** * * Set timeout in seconds for Select statements. * */ 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; } } }
希望对人们有所帮助!
在某些情况下,您无法在类中访问类似Adapter的成员,因为它们被定义为类的私有 。
幸运的是,向导将生成部分类,这意味着您可以扩展它们。 如[Piebald的[此主题] [1]中所述,您可以编写自己的属性来设置select-commands的超时。
通常,你会这样做:
partial class FooTableAdapter { /** * * Set timeout in seconds for Select statements. * */ public int SelectCommandTimeout { set { for ( int n=0; n < _commandCollection.Length; ++n ) if ( _commandCollection[n] != null ) ((System.Data.SqlClient.SqlCommand)_commandCollection[n]) .commandTimeout = value; } } }
请注意,我自己并没有真正尝试过,但它似乎是一个可行的解决方案。
假设您的数据集名为MySET。
有一个名为MyTable的表
MySETTableAdapters.MyTableTableAdapter fAdapter = new MySETTableAdapters.MyTableTableAdapter(); fAdapter.Adapter.SelectCommand.CommandTimeout = ;
通过以秒为单位提供TableAdapter和Time来调用ChangeTimeout函数。
this.ChangeTimeout(this.taTest, 500);
function:
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; }
如果使用部分类,请使用正确的命名空间。 可能[您的数据集名称] +“TableAdapters”。示例:
命名空间MyProject.DataSet1TableAdapters
您可以打开Properties文件夹,打开Settings.settings并更改连接字符串的Timeout属性。
以下是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)
这个现在有点老了,并怀疑这个解决方案与每个人都无关,但我最终使用AniPol的解决方案来覆盖ObjectDataSource控件,如下所示:
public class MyObjectDataSource : ObjectDataSource { public MyObjectDataSource() { this.ObjectCreated += this.MyObjectDataSource_ObjectCreated; } private void MyObjectDataSource_ObjectCreated(object sender, ObjectDataSourceEventArgs e) { var objectDataSourceView = sender as ObjectDataSourceView; if (objectDataSourceView != null && objectDataSourceView.TypeName.EndsWith("TableAdapter")) { var adapter = e.ObjectInstance; PropertyInfo adapterProp = adapter.GetType() .GetProperty( "CommandCollection", BindingFlags.NonPublic | BindingFlags.GetProperty | BindingFlags.Instance); if (adapterProp == null) { return; } SqlCommand[] commandCollection = adapterProp.GetValue(adapter, null) as SqlCommand[]; if (commandCollection == null) { return; } foreach (System.Data.SqlClient.SqlCommand cmd in commandCollection) { cmd.CommandTimeout = 120; } } } }
我喜欢这个; 右键单击Fill()
或GetX()
函数,然后单击菜单中的Goto Defination
GetX()
。
您将看到DATATABLE的源代码。 并找到;
private global::System.Data.SqlClient.SqlCommand[] _commandCollection;
来自dataadapter类的命令行。 并将私人变为公众。
现在您可以访问_commandCollection,并且可以更改所有属性。
但是当你添加或更改任何Filed表单DESIGNER时要小心,公众将通过自动生成系统再次私有。
而且,当你完成调用Fill或Get Function时,你必须重置_commandColleciton
调用这个函数( InitCommandCollection()
)
public void InitCommandCollection() {}
这个function也是autogen私有的,你也必须改为公开!
例:
dsIslemlerTableAdapters.tblIslemlerTableAdapter _t = new dsIslemlerTableAdapters.tblIslemlerTableAdapter(); dsIslemler.tblIslemlerDataTable _m = new dsIslemler.tblIslemlerDataTable(); _t._commandCollection[0].CommandText = "Select * From tblIslemler Where IslemTarihi>='' And IslemTarihi<=''"; _m = _t.GetData(); _t.InitCommandCollection();
扩展了帮助我很多的tableadapters已经非常有用的答案,我还需要读出实际的超时值。 从而:
namespace XTrans.XferTableAdapters { public partial class FooTableAdapter { int? _timeout = null; /// ///Get or set the current timeout in seconds for Select statements. /// public int CurrentCommandTimeout { get { int timeout = 0; if (_timeout != null) { timeout = (int)_timeout; } else { for (int i = 0; i < this.CommandCollection.Length; i++) if (this.CommandCollection[i] != null) timeout = this.CommandCollection[i].CommandTimeout; } return timeout; } 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; _timeout = value; } } } } }
似乎有一种更方便的方法来做到这一点。 这是我发现的快速回顾。
假设我将一个名为MyDB的(类库)项目添加到我的解决方案中。 在该项目中,我添加了一个名为“Data”的DataSet。 在该数据集中,我拖动了一个名为“X”的表。
我在设计图面上得到的是一个对象,它显示我有一个名为“XTableAdapter”的对象。
我现在打开生成的代码Data.Designer.cs,然后查找XTableAdapter。 当我找到它时,我注意到它包含在名称空间MyDB.DataTableAdapters中 – 它只是项目名称,“MyDB”,DataSet名称,“Data”和“TableAdapters”的串联。
有了这个,我现在回到类库,仍然称为Class1.cs(我现在将忽略它)。
我将其命名空间从MyDB更改为MyDB.DataTableAdapters。
我将类声明更改为公共部分类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);
较少的麻烦,较少的烦恼,较少的reflection(好,没有),较少的填充。
上述就是C#学习教程:如何更改表适配器的命令超时分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注---计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1013821.html