2014-07-23 17 views
6

Ho sei linee di parametri come questo:Come aggiungere più parametri al comando SQL in un'unica istruzione?

cmd.Parameters.AddWithValue("@variable1", myvalue1); 
    cmd.Parameters.AddWithValue("@variable2", myvalue2); 
    cmd.Parameters.AddWithValue("@variable3", myvalue3); 

e così via.

C'è un modo per comprimere questo un po 'senza inserire direttamente in cmd.CommandText?

Modifica: Credo che avrei potuto usare un buon vecchio stile. Ho deciso di restare con questo però.

+0

io non sono sicuro perché si sta cercando di comprimere questo, ma io sono abbastanza sicuro che il modo in cui si sta facendo è la più modo semplice e compatto. –

+1

Non c'è modo di renderlo più corto. Perché vuoi? Potresti usare una libreria completamente diversa o qualcosa che la automatizza, ma non sarebbe più economica, ma solo diversa. –

+1

Solo curiosità onestamente. Risulta che non c'è un modo più breve! – user3808188

risposta

5

Per quanto ne so, il codice è il più compatto possibile in termini di numero di righe, tuttavia è possibile utilizzare lo List<SqlParameter> con la sintassi di inizializzatore dell'oggetto per avere solo una riga terminata da un punto e virgola per creare l'elenco di parametri, quindi passare che lista come la matrice di parametri attesi dal metodo AddRange

List<SqlParameter> prm = new List<SqlParameter>() 
{ 
    new SqlParameter("@variable1", SqlDbType.Int) {Value = myValue1}, 
    new SqlParameter("@variable2", SqlDbType.NVarChar) {Value = myValue2}, 
    new SqlParameter("@variable3", SqlDbType.DateTime) {Value = myValue3}, 
}; 
cmd.Parameters.AddRange(prm.ToArray()); 

si noti che con questo approccio è necessario definire correttamente il tipo di dati del parametro. Nel mio esempio ho usato alcuni tipi arbitrari per mostrare la sintassi corretta

Un po 'fuori tema, penso che in questo contesto generale sia interessante sottolineare che AddWithValue non è da considerare quando si vuole ottenere il migliore prestazione possibile.

In questo articolo su MSDN How data access code affects database perfomance è spiegato bene perché si dovrebbe evitare il metodo AddWithValue per motivi di prestazioni.
In breve, l'utilizzo di AddWithValue potrebbe essere un problema per lo Sql Server Optimizer perché i parametri della stringa di tipo vengono passati con la dimensione uguale alla lunghezza corrente della stringa. Ma questo costringerà lo Sql Server Optimizer a scartare il piano di query creato per una precedente chiamata identica ma con una stringa di lunghezza diversa.
È preferibile chiamare il costruttore SqlParameter specificando il tipo e la dimensione del parametro e non preoccuparsi di come effettuare il compress the size delle chiamate.

+2

Ho paura di non vedere come questo sia più compresso del codice originale. –

+0

Non compresso è solo una riga anziché tre righe (escluso l'ultimo AddRange ovviamente) – Steve

+0

ma si aggiungono linee aggiuntive creando un elenco ... – DotN3TDev

1

Solo per amor di discussione, utilizzando il codice di esempio che hai dato in cui le variabili proc memorizzati vengono letteralmente chiamati variabe1, variable2, ecc ... si potrebbe fare qualcosa di simile:

string[] myValues = new string[] { "myvalue1", "myvalue2", "myvalue3", "myvalue4", "myvalue5", "myvalue6" }; 
for (int i = 0; i < 6; i++) { cmd.Parameters.AddWithValue("@variable" + (i + 1),myValues[i]); } 

2 righe di codice brutto ... LOL

Un ciclo come questo può tornare utile se avessi detto 25-50 valori, anche se non lo vedo molto spesso. E si potrebbe utilizzare 2 campi, uno per i nomi delle variabili e uno per i valori, fino a quando gli indici corrispondono, allora questo dovrebbe funzionare:

string[] myVarNames = new string[] { "variable1", "variable2", "variableThree", "variable4our", "variableFIVE", "variableSIX" }; 
string[] myValues = new string[] { "myvalue1", "myvalue2", "myvalue3", "myvalue4", "myvalue5", "myvalue6" }; 

for (int i = 0; i < 6; i++) 
{ 
    cmd.Parameters.AddWithValue("@" + myVarNames[i], myValues[i]); 
} 
+1

Ciò potrebbe ispirare una soluzione interessante per OleDB e ODBC, che hanno parametri ordinati senza nome. – Larry

+0

Sì, ho usato la seconda opzione in modo esteso in passato. – user3808188

+1

Invece di due array, l'uso di un 'dizionario ' eliminerebbe la preoccupazione degli indici non corrispondenti. – ShooShoSha

3

ho preso la questione letteralmente: " ...in una dichiarazione" :)

codice di Steve è bello, ma può essere semplificato un po 'di più con la più canonica SqlParameter costruttore e dichiarazione implicita array:

cmd.Parameters.AddRange(new [] 
    { 
     new SqlParameter("@variable1", myValue1}, 
     new SqlParameter("@variable2", myValue2}, 
     new SqlParameter("@variable3", myValue3}, 
    }); 
+2

A meno che uno di questi valori sia un numero intero con valore zero. Vedi http://stackoverflow.com/questions/9999751/difference-between-parameters-add-and-parameters-addwithvalue – Steve

+0

Hai ragione. Lanciare un hard coded 0 come oggetto 'nuovo SqlParameter (" @ param ", (oggetto) 0)' farebbe il trucco, ma sono d'accordo che non è bello. – Larry

+1

No, non lo ero. Grazie per il collegamento, è interessante quanto lo scoraggiamento: "Sempre specificando il giusto tipo di dati, lunghezza, precisione e scala garantirai che non stai facendo la coercizione del tipo di dati al momento dell'esecuzione". - ARGH Sono troppo pigro! Ma lo ricorderò per situazioni estreme in cui le prestazioni sono critiche. – Larry

0

Penso che questa sarà leggere molto bene come un uno di linea come questa:

Usage:

// One liner to create and set SqlCommand parameters 
cmd.SetParameters(Parameter("@variable1", myvalue1), Parameter("@variable2", myvalue2), Parameter("@variable3", myvalue3)); 

per supportare l'uno di linea è necessario creare una funzione per avvolgere il parametro SQL come un fascio semantica (Tuple simili) come segue:

public SqlParameter Parameter(string name, object value) 
{ 
    return new SqlParameter(name, value); 
} 

Creare una classe statica con un metodo di estensione per darci lo zucchero sintattico che stiamo cercando. Si noti l'uso della parola chiave param. che consente di impostare i parametri multipli nella chiamata precedente a SetParameters.

public static class SqlDataUtils 
{ 
    public static void SetParameters(this SqlCommand command, params SqlParameter[] parameters) 
    { 
     command.Parameters.AddRange(parameters); 
    } 
} 

Questa risposta si ispira alla risposta accettata a Key value pairs in C# Params da Bryan Watts

Problemi correlati