2009-06-22 16 views
7

Preámbulo:¿Establecer CommandTimeout utilizado en Strongly Typed DataSet TableAdapter?

Por lo tanto, en los últimos 5 años más o menos varias aplicaciones y herramientas se han escrito aquí en mi empresa. Desafortunadamente, muchas de las personas que desarrollaron estas aplicaciones utilizaron conjuntos de datos fuertemente tipados. Estoy considerando prohibirlos en nuestra tienda ahora ...

Uno de los procesos más grandes que utilizaba conjuntos de datos fuertemente tipados ahora se está agotando ... pretendo para reescribir todo el proceso usando nHibernate en los próximos meses, pero por el momento necesito cambiar el tiempo de espera para permitir a nuestros usuarios usar el proceso, aunque lentamente ... Desafortunadamente, Microsoft hizo los métodos de tiempo de comando privados, así que no puedo acceder ellos directamente.

La única solución que he encontrado hasta ahora es crear una clase parcial para cada TableAdapter e incluyen los métodos de tiempo de espera allí ...

Esto es bastante torpe ya que significaría la adición de las clases parciales durante bastante pocos TableAdapters ...

¿Alguien sabe de una manera más eficiente de manejar esto?

Respuesta

2

No dice qué idioma está utilizando. A continuación se presenta en VB.NET desde que pasó a encontrar un ejemplo de ello en primer lugar:

Namespace AdventureWorksPurchasingDSTableAdapters 
    Partial Public Class SalesOrderHeaderTableAdapter 
    Public Property SelectCommandTimeout() As Integer 
     Get 
     Return Adapter.SelectCommand.CommandTimeout 
     End Get 
     Set(ByVal value As Integer) 
     Adapter.SelectCommand.CommandTimeout = value 
     End Set 
    End Property 
    End Class 
End Namespace 
+0

Correcto, pero eso es lo que trato de evitar ... Individualmente es fácil de hacer ... Si tiene varios cientos de adaptadores de tabla para varios cientos de conjuntos de datos, en realidad no es muy viable. – Gary

+0

No puedo pensar qué más podrías hacer. No hay una propiedad global CommandTimeout. Si lo hubiera, todavía tendría que establecer las propiedades individuales SqlCommand.CommandTimeout. –

+0

¿Por qué no se puede ajustar la propiedad CommandTimeout en Dataset Designer? ¿Y por qué todavía son 30 segundos cuando cambio el tiempo de espera de conexión a 300 segundos? Por cierto, ¿cuál es la diferencia entre estos? Gracias de antemano ... –

2

Ok, por lo que yo puedo decir que no hay acceso directo/solución para estas situaciones. Gracias a John por intentarlo.

Mi mejor consejo es no utilizar MS conjuntos de datos fuera del prototipado rápido y sucio ... Cuando su aplicación crece y necesita expandirse sólo tienes sucia la izquierda :)

+0

Esta es una base bastante estrecha para condenar los DataSets tipeados. Sin embargo, es una gran base para una sugerencia de función en Connect (http://connect.microsoft.com/visualstudio/). Una vez que haya publicado la sugerencia, edite esta respuesta con la URL de la sugerencia, para que otros puedan votar por la importancia que sentimos. –

+0

Bueno, este problema no es la única base para esa afirmación ... El problema más importante que tengo con los datasets es la falta de valores predeterminados inteligentes ... Si su archivo de configuración no tiene la cadena de conexión correcta, entonces se predetermina a cualquier cadena de conexión con la que se creó ... Mi instinto sobre ese tema es que en cualquier situación donde haya ambigüedad, entonces la única respuesta correcta es lanzar una excepción y morir ... – Gary

+0

Voy a poner la sugerencia en Connect más tarde esta víspera, no estaba ignorando su sugerencia :) – Gary

3

I "resuelto" esto usando la reflexión. (Si bien el modelo VS2010 permite exponer la propiedad Adapter, la SelectCommand, etc, habrá null antes GetData, por ejemplo.)

El "código feo pero el código funcional" actualmente estoy usando:

void SetAllCommandTimeouts(object adapter, int timeout) 
{ 
    var commands = adapter.GetType().InvokeMember(
      "CommandCollection", 
      BindingFlags.GetProperty | BindingFlags.Instance | BindingFlags.NonPublic, 
      null, adapter, new object[0]); 
    var sqlCommand = (SqlCommand[])commands; 
    foreach (var cmd in sqlCommand) 
    { 
     cmd.CommandTimeout = timeout; 
    } 
} 

// unfortunately this still requires work after a TableAdapter is obtained... 
var ta = new MyTableAdapter(); 
SetAllCommandTimeouts(ta, 120); 
var t = ta.GetData(); 

No es posible escribir el adaptador mejor (aunque quizás en un Component), debido a la falta de interfaces/base común.

Happy coding.

+0

Me ayudó mucho a solucionar mi problema. :) –

0

He resuelto este problema fácilmente. Ingresé al código de diseñador de mi conjunto de datos (dataset1.designer.vb) y encontré los siguientes comandos, Me._commandCollection(0), Me._commandCollection(1) a Me._commandCollection(5), porque tengo cinco comandos totales que se ejecutan en mi base de datos de SQL Server 2008. En cada uno (0 a 5) de estos comandos escribí Me._commandCollection(0).CommandTimeout = 60, donde cambio 0 al siguiente número para los otros cuatro comandos. Cada uno de los cinco comandos tiene un bloque de código, de los cuales, dos bloques aparecen a continuación para proporcionar un ejemplo.

Me._commandCollection = New Global.System.Data.SqlClient.SqlCommand(5) {} 

Me._commandCollection(0) = New Global.System.Data.SqlClient.SqlCommand() 

Me._commandCollection(0).Connection = Me.Connection 

Me._commandCollection(0).CommandTimeout = 60 

Me._commandCollection(0).CommandText = "SELECT MK_QR_SUB_AND_DETAIL.*" & _ "Global.Microsoft.VisualBasic.ChrW(13) & Global.Microsoft.VisualBasic.ChrW(10)" & _ "FROM MK_QR_SUB_AND_DETAIL" 

Me._commandCollection(0).CommandType = Global.System.Data.CommandType.Text  

Me._commandCollection(1) = New Global.System.Data.SqlClient.SqlCommand() 

Me._commandCollection(1).Connection = Me.Connection 

Me._commandCollection(1).CommandTimeout = 60 

Me._commandCollection(1).CommandText = "dbo.spQtrRptTesting_RunInserts_Step1of4" 

Me._commandCollection(1).CommandType = Global.System.Data.CommandType.StoredProcedure 

Me._commandCollection(1).Parameters.Add(New Global.System.Data.SqlClient.SqlParameter("@RETURN_VALUE", Global.System.Data.SqlDbType.Int, 4, Global.System.Data.ParameterDirection.ReturnValue, 10, 0, Nothing, Global.System.Data.DataRowVersion.Current, False, Nothing, "", "", "")) 

Me._commandCollection(1).Parameters.Add(New Global.System.Data.SqlClient.SqlParameter("@pStartADate", Global.System.Data.SqlDbType.[Date], 3, Global.System.Data.ParameterDirection.Input, 10, 0, Nothing, Global.System.Data.DataRowVersion.Current, False, Nothing, "", "", "")) 

Me._commandCollection(1).Parameters.Add(New Global.System.Data.SqlClient.SqlParameter("@pEndADate", Global.System.Data.SqlDbType.[Date], 3, Global.System.Data.ParameterDirection.Input, 10, 0, Nothing, Global.System.Data.DataRowVersion.Current, False, Nothing, "", "", "")) 

Me._commandCollection(1).Parameters.Add(New Global.System.Data.SqlClient.SqlParameter("@pStartBDate", Global.System.Data.SqlDbType.[Date], 3, Global.System.Data.ParameterDirection.Input, 10, 0, Nothing, Global.System.Data.DataRowVersion.Current, False, Nothing, "", "", "")) 

Me._commandCollection(1).Parameters.Add(New Global.System.Data.SqlClient.SqlParameter("@pEndBDate", Global.System.Data.SqlDbType.[Date], 3, Global.System.Data.ParameterDirection.Input, 10, 0, Nothing, Global.System.Data.DataRowVersion.Current, False, Nothing, "", "", "")) 
+0

Advertencia: nunca edite los archivos 'designer' manualmente. Este es un código generado automáticamente, todo lo que escriba puede ser sobreescrito por Visual Studio cuando regenere el código. –

0

He decidido crear una nueva clase en el archivo DataSet.cs que deriva las clases TableAdapter y en el constructor comprueba el App.config para commandtimeouts. También agrego la capacidad de especificar un tiempo de espera de comando para un adaptador de tabla específico y, si eso no está presente, entonces verifique si hay un valor global.

public class ImprovedMyTableAdapter : MyTableAdapter 
{ 
    public ImprovedMyTableAdapter() 
     : base() 
    { 
     int parsedInt = int.MinValue; 
     string appSettingValue = System.Configuration.ConfigurationManager.AppSettings["MyTableAdapter_CommandTimeout"]; 
     if (string.IsNullOrEmpty(appSettingValue)) 
      appSettingValue = System.Configuration.ConfigurationManager.AppSettings["CommandTimeout"]; 
     if (!string.IsNullOrEmpty(appSettingValue) && int.TryParse(appSettingValue, out parsedInt)) 
     { 
      foreach (var command in this.CommandCollection) 
       command.CommandTimeout = parsedInt; 
     } 
    } 
} 
0

No me meteré con el código del diseñador de DataSet directamente por error, se cambiará si alguna vez actualiza algo en el diseñador. En su lugar, cree una clase parcial para el adaptador de tabla y asígnele un constructor que acepte el parámetro de tiempo de espera del comando y llame al constructor sin parámetros.

A continuación, recorra el CommandCollection y establezca el tiempo de espera en el argumento de tiempo de espera pasado.

Cuestiones relacionadas