我正在使用Visual Studio 2008和C#。
我有一个.xsd文件,它有一个表适配器。我想更改表适配器的命令超时。
感谢您的帮助。
答案 0 :(得分: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);
}
}
}
答案 1 :(得分:10)
通过一些小的修改,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.CommandTimeout = 60;在this.FooTableAdapter.Fill();
之前的某个地方如果需要更改许多表适配器的超时,可以创建一个通用的扩展方法,让它使用反射来更改超时。
/// <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”类可以限制它。)
答案 2 :(得分:4)
我使用Mitchell Gilman的解决方案时遇到了一些问题,我最终能够解决这个问题。
首先,我需要确保使用正确的命名空间。我花了一段时间才弄清楚xsd数据集的Designer文件实际上包含两个名称空间,一个用于一般数据集,另一个用于表适配器。所以首先要注意的是应该使用表适配器的命名空间,而不是一般的数据集。
其次,当第一次使用timeout命令时,可能不会始终初始化commandcollection。为了解决这个问题,我调用了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;
}
}
}
希望对人们有所帮助!
答案 3 :(得分:2)
在某些情况下,您无法访问类中的 Adapter 等成员,因为它们被定义为类的私有。
幸运的是,向导将生成部分类,这意味着您可以扩展它们。如[Piebald的[此主题] [1]中所述,您可以编写自己的属性来设置select-commands的超时。
通常,你会这样做:
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;
}
}
}
请注意,我自己并没有尝试过,但这似乎是一个可行的解决方案。
答案 4 :(得分:1)
假设您的数据集名为MySET
有一个名为MyTable的表
MySETTableAdapters.MyTableTableAdapter fAdapter =
new MySETTableAdapters.MyTableTableAdapter();
fAdapter.Adapter.SelectCommand.CommandTimeout = <fill inyour value here>;
答案 5 :(得分:1)
通过以秒为单位提供TableAdapter和Time来调用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;
}
答案 6 :(得分:0)
如果使用部分类,请使用正确的命名空间。可能[您的数据集名称] +“TableAdapters”。示例:
命名空间MyProject.DataSet1TableAdapters
答案 7 :(得分:0)
您可以打开Properties文件夹,打开Settings.settings并更改连接字符串的Timeout属性。
答案 8 :(得分:0)
我喜欢这个;右键单击Fill()
或GetX()
功能,然后点击菜单中的Goto Defination
。
您将看到DATATABLE的源代码。并找到;
private global::System.Data.SqlClient.SqlCommand[] _commandCollection;
来自dataadapter类的命令行。 并将私人变为公众。
现在您可以访问_commandCollection,并且可以更改所有属性。
但是当你添加或更改任何Filed表格DESIGNER时要小心,公众将通过自动生成系统再次私有。
此外,当您完成调用Fill或Get Function时,您必须重置_commandColleciton
调用此函数(InitCommandCollection()
)
public void InitCommandCollection() {}
此功能也是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();
答案 9 :(得分:0)
以下是来自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)
答案 10 :(得分:0)
这个现在有点老了,并怀疑这个解决方案与每个人都不相关,但我最终使用AniPol's解决方案来覆盖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;
}
}
}
}
答案 11 :(得分:0)
扩展已帮助我很多的tableadapters已经非常有用的答案,我还需要读出实际的超时值。因此:
namespace XTrans.XferTableAdapters
{
public partial class FooTableAdapter
{
int? _timeout = null;
///<summary>
///Get or set the current timeout in seconds for Select statements.
///</summary>
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;
}
}
}
}
}
答案 12 :(得分:0)
似乎有一种更方便的方法来做到这一点。这是对我发现的内容的快速回顾。
我想说我在我的解决方案中添加了一个名为MyDB的(类库)项目。在该项目中,我添加了一个名为&#34; Data&#34;的DataSet。在该数据集中,我拖了一个名为&#34; X&#34;。
的表我在设计界面得到的是一个对象,它表明我有一个名为&#34; XTableAdapter&#34;的对象。
我现在打开生成的代码Data.Designer.cs,然后查找XTableAdapter。 当我找到它时,我注意到它包含在命名空间MyDB.DataTableAdapters中 - 它只是项目名称的连接,&#34; MyDB&#34;,DataSet的名称,&#34 ;数据&#34;和&#34; TableAdapters&#34;。
有了这个,我现在回到类库,仍称为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);
减少麻烦,减少烦恼,减少反思(嗯,没有),减少填充。
答案 13 :(得分:0)
如果转到[DataSet的名称] .Designer.cs,它是在解决方案中的数据集文件下添加的文件,然后搜索:
$xml = "<?xml version=\"1.0\" encoding=\"utf-8\"?>
<request>
<request-type>9</request-type>
<terminal-id>".$termid."</terminal-id>
<login>".$login."</login>
<password-md5>".$pwd."</password-md5>
<message txn-id=\"".$txn."\" sign=\"".$sign."\">
<to>
<source-address>".$source_address."</source-address>
<destination-address>".$mobile_number."</destination-address>
<data-encoding>1</data-encoding>
<text>".$message."</text>
</to>
</message>
</request>";
$ch = curl_init();
$url = "http://gate.payvand.tj/xml/";
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, Array("Content-Type: text/xml"));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $xml);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FRESH_CONNECT, true);
curl_setopt($ch, CURLOPT_FORBID_REUSE, true);
curl_setopt($ch, CURLOPT_TIMEOUT, 60);
这是一个函数,您应该能够为在表适配器中定义的函数设置属性。
该函数的第一行是
private void InitCommandCollection();
,然后在每个功能的下一行中,设置
this._commandCollection = new global::System.Data.IDbCommand[<number of function defined in a table adapater>];
其中0表示没有限制,并且该功能不会因超时而停止,并且可以将其设置为10、20、30或1000,依此类推
答案 14 :(得分:0)
整天挠头后,我终于得到了解决方案。设计完.xsd文件后,您需要做的是转到您的dataset.designer.cs页面,该页面是一个自动生成的页面,并将代码更改为下面提供的代码。真的行。试试看。
protected global::System.Data.SqlClient.SqlCommand[] CommandCollection
{
get
{
if ((this._commandCollection == null))
{
this.InitCommandCollection();
_commandCollection[0].CommandTimeout = 0;
}
_commandCollection[0].CommandTimeout = 0;
return this._commandCollection;
}
}