2009-06-22 20 views
7

Preambolo:Impostare CommandTimeout utilizzato in DataSet TableAdapter fortemente tipizzato?

Così, negli ultimi 5 anni o giù di lì diverse applicazioni e gli strumenti sono stati scritti qui alla mia azienda. Sfortunatamente molte delle persone che hanno sviluppato queste applicazioni hanno utilizzato set di dati fortemente tipizzati, sto pensando di metterli fuori legge nel nostro negozio ora ...

Uno dei processi più grandi che utilizza set di dati fortemente tipizzati sta scadendo ora ... Intendo per riscrivere l'intero processo usando nHibernate nei prossimi mesi ma per il momento ho bisogno di cambiare il timeout per permettere ai nostri utenti di usare il processo, anche se lentamente ... Purtroppo Microsoft ha reso privati ​​i metodi commandtimeout quindi non posso accedere loro direttamente.

L'unica soluzione che ho incontrato finora è quello di creare una classe parziale per ogni TableAdapter e comprendono i metodi di timeout lì ...

Questo è abbastanza goffo, poiché ciò significherebbe l'aggiunta di classi parziali per un periodo piuttosto alcuni TableAdapters ...

Qualcuno sa di un modo più efficiente per gestire questo?

risposta

2

Non si dice quale lingua si sta utilizzando. Quello che segue è in VB.NET da quando mi è capitato di trovare un tale esempio prima:

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

Giusto, ma questo è quello che sto cercando di evitare di fare ... Singolarmente è facile da fare ... Se hai diverse centinaia di adattatori da tavolo per diverse centinaia di set di dati non è davvero molto praticabile. – Gary

+0

Non riesco a pensare a cos'altro potresti fare. Non esiste una proprietà CommandTimeout globale. Se esistesse, sarebbe comunque in qualche modo necessario impostare le singole proprietà SqlCommand.CommandTimeout. –

+0

Perché non è possibile regolare la proprietà CommandTimeout in Dataset Designer? E perché sono ancora 30 secondi quando cambio Timeout connessione a 300 secondi? A proposito, qual è la differenza tra questi? Grazie in anticipo ... –

2

Ok, per quanto posso dire non ci sono scorciatoie/soluzione per queste situazioni. Grazie a John per aver provato.

Il mio miglior consiglio è di non utilizzare i set di dati MS al di fuori di prototipazione rapida e sporca ... Quando l'applicazione cresce e necessita di essere ampliato hai solo la sporca sinistra :)

+0

Questa è una base abbastanza ristretta per condannare DataSet digitati. Tuttavia, è un'ottima base per un suggerimento di funzionalità su Connect (http://connect.microsoft.com/visualstudio/). Una volta pubblicato il suggerimento, modifica questa risposta con l'URL del suggerimento, in modo che gli altri possano votare per l'importanza che riteniamo sia. –

+0

Bene, questo problema non è l'unica base per questa affermazione ... Il singolo problema più grande che ho con i set di dati è la mancanza di impostazioni predefinite intelligenti ... Se il tuo file di configurazione non ha la stringa di connessione corretta, allora il valore predefinito per qualsiasi stringa di connessione è stato creato con ... Il mio istinto su quel problema è che in ogni situazione in cui c'è qualche ambiguità, l'unica risposta corretta è di lanciare un'eccezione e morire ... – Gary

+0

Metterò il suggerimento su Connect dopo questa vigilia, non ignoravo il tuo suggerimento :) – Gary

3

I "risolto" questo usando la riflessione. (Mentre il modello VS2010 consente di esporre la proprietà Adapter, il SelectCommand, ecc, sarà null prima GetData, per esempio.)

Il "brutto codice, ma codice funzionale" Attualmente sto 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(); 

Non è davvero possibile digitare l'adattatore meglio (anche se forse su un Component), a causa della mancanza di base/interfacce comuni.

Felice codifica.

+0

Molto utile per risolvere il mio problema. :) –

0

Ho risolto facilmente questo problema. Sono entrato nel codice del mio set di dati del dataset (dataset1.designer.vb) e ho trovato i seguenti comandi, Me._commandCollection(0), Me._commandCollection(1) a Me._commandCollection(5), perché ho cinque comandi totali eseguiti contro il mio database SQL Server 2008. In ciascuno (da 0 a 5) di questi comandi ho scritto Me._commandCollection(0).CommandTimeout = 60, dove cambio 0 al numero successivo per gli altri quattro comandi. Ognuno dei cinque comandi ha un blocco di codice, di cui due sotto appaiono per fornirti un esempio.

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

Attenzione: non modificare mai manualmente i file 'designer'. Questo è codice generato automaticamente, tutto ciò che scrivi in ​​esso può essere sovrascritto da Visual Studio quando rigenererà il codice. –

0

ho deciso di creare una nuova classe nel file DataSet.cs che deriva le classi TableAdapter e nel costruttore controlla l'App.config per commandtimeouts. Aggiungo anche la possibilità di specificare un timeout di comando per un adattatore di tabella specifico e, se questo non è presente, verificare la presenza di un valore globale.

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

io non pasticcio con il codice del designer DataSet direttamente b/c sarà cambiato se mai aggiornare nulla nella finestra di progettazione. Creare invece una classe parziale per l'adattatore da tavolo e assegnargli un costruttore che accetta il parametro timeout del comando e chiama il costruttore senza parametri.

Quindi passare attraverso CommandCollection e impostare il timeout sull'argomento timeout passato.

Problemi correlati