I\'m using Visual Studio 2008 with C#.
I have a .xsd file and it has a table adapter. I want to change the table adapter\'s command timeout.
Thanks for your
Say your dataset is called MySET.
There is one table called MyTable
MySETTableAdapters.MyTableTableAdapter fAdapter =
new MySETTableAdapters.MyTableTableAdapter();
fAdapter.Adapter.SelectCommand.CommandTimeout = <fill inyour value here>;
There seems to be a more convenient way to do this. Here's a quick recap of what I found.
Let's say I add a (class library) project called MyDB to my solution. Into that project I add a DataSet called "Data". And into that dataset, I drag a table called "X".
What I get on the design surface is an object that shows that I have an object called "XTableAdapter".
I now open the generated code, Data.Designer.cs, and look for XTableAdapter. When I find it, I note that it's contained in namespace MyDB.DataTableAdapters - which is just a concatenation of the name of the project, "MyDB", the name of the DataSet, "Data", and "TableAdapters".
With that in hand, I now go back to the class library, still called Class1.cs (which I'll ignore for now).
I change its namespace from MyDB to MyDB.DataTableAdapters.
I change the class declaration to public partial class XTableAdapter, and make it look like this:
using System.Data.SqlClient;
namespace MyDB.DataTableAdapters
{
public partial class XTableAdapter
{
public void SetTimeout(int seconds)
{
foreach (SqlCommand cmd in CommandCollection)
{
cmd.CommandTimeout = seconds;
}
}
}
}
The calling sequence could hardly be clearer:
int TwoMinutes = 120;
XTableAdapter.SetTimeout(TwoMinutes);
Less muss, less fuss, less reflection (well, none), less filling.
I have investigated this issue a bit today and come up with the following solution based on a few sources. The idea is to create a base class for the table adapter too inherit which increases the timeout for all commands in the table adapter without having to rewrite too much existing code. It has to use reflection since the generated table adapters don't inherit anything useful. It exposes a public function to alter the timeout if you want to delete what i used in the constructor and use that.
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);
}
}
}
Call ChangeTimeout Function by providing the TableAdapter and Time in seconds.
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;
}
I had a couple of issues with using Mitchell Gilman's solution that I was eventually able to workaround.
First of all, I needed to make sure to use the right namespace. It took me a while to figure out that Designer file for the xsd data set actually contains two namespaces, one for the data set in general and one for the table adapters. So the first thing is to note is that the namespace for the table adapter should be used, not for the data set in general.
Secondly, the commandcollection may not always be initialized when the timeout command is used for the first time. To work around this, I called the InitCommandCollection command if this was the case.
So the adapted solution I used was
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;
}
}
}
Hope that's helpful to people!
Expanding on the already very useful answers for tableadapters that helped me a lot, I also had the need to read out the actual timeout value. Thus:
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;
}
}
}
}
}