Atomatizzare il popolamento di SqlCommand.parameters

lunedì 29 settembre 2008 - 13.53

gabriel81 Profilo | Junior Member

Ciao a tutti!
A qualcuno di voi è già venuto in mente qualche soluzione per automatizzare il popolamento dei paramentri di un comando SQL?

Io pensavo ad una funzione che va a leggersi sul form tutti i controlli che hanno una determinata caratteristica, e per ciascuno di questi si crea
l'oggetto SQLClient.SQLParameter oportunamente configurato(Nome,Valore e magri anche tipo) e lo aggiunge alla collezione.
Questo per evitare cose tipo:

Dim Cmd As SqlClient.SqlCommand = New SqlClient.SqlCommand("SPN_FORNITORI", Conn)
Cmd.CommandType = CommandType.StoredProcedure
Cmd.Parameters.AddWithValue("@RagSociale", "DOTNETHELL.IT spa")
Cmd.Parameters.AddWithValue("@CODPAGAMENTO", 1)

[................... n parametri di tabella!!!]

Cmd.Parameters.Add("@ID", SqlDbType.Int)
Cmd.Parameters("@ID").Direction = ParameterDirection.Output



Che ne dite?
Esistono delle soluzioni migliori?
Avete già realizzato qualcosa voi?
Grazie 1000 in anticipo

Brainkiller Profilo | Guru

>Ciao a tutti!
>A qualcuno di voi è già venuto in mente qualche soluzione per
>automatizzare il popolamento dei paramentri di un comando SQL?

Eh direi di sì

>Che ne dite?
>Esistono delle soluzioni migliori?

Eh beh,
io avevo fatto una cosa del genere. E riuscivo a enumerare tramite la Reflection gli oggetti della Form e andavo a riempire la Collection Parameters che poi inviavo al DAL e lui eseguiva. E' un po' lunga perchè per fare una cosa del tutto automatica devi usare o file esterni di configurazione o ricavare dinamicamente anche i tipi di dati delle colonne dal database sottostante. Però tutto ciò ti porta a una riduzione enorme di codice.

Oppure puoi usare LINQ con Stored Procedure. LINQ ti crea classe e metodi per richiamare la stored procedure. Il risultato è che avrai un metodo che richiami, gli passi tutti i parametri della Form e sei a posto. Quindi ciò che prima scrivevi in 10-15-20 e più righe ora lo fai con una riga.

Ciao

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

gabriel81 Profilo | Junior Member

Ma se io utilizzassi dei controlli personalizzati, dotati magari di una proprietà pubblica che espone una struttura tipo:

IncludiNelleStoredProcedure as boolean
TipoDiDati as SQLTipe
ecc
ecc

e poi facendo il ciclo dei controlli sul form filtro in base al cast?

Ti dico questo perchè sono abbastanza neofita e delle tecniche che hai esposto tu, non conosco nemmeno l'ombra.... purtroppo...

Brainkiller Profilo | Guru

>Ma se io utilizzassi dei controlli personalizzati, dotati magari
>di una proprietà pubblica che espone una struttura tipo:

Cosa intendi per controlli personalizzati ?

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

gabriel81 Profilo | Junior Member

Intendo delle combobox e textbox ereditati.
Siccome sono pigro a scrivere, ho creato delle combobox personalizzate, e dei textbox personalizzati
Le textbox automatizzano cose noiose come il cambiare colore di sfondo quando prendono il focus
Le combo hanno funzioni integrate di autopopolamento (passandogli solo il nome della Stored Procedure) in un thread differente.

P.S.: Visto che sei un guru, ti faccio una piccola domanda off-thread: ho deciso di impostare le mie applicazioni con SQL server express utilizzando esclusivamente SP, faccio bene? ho letto in giro che sono + performanti che le semplici istruzioni sql

Brainkiller Profilo | Guru

>Intendo delle combobox e textbox ereditati.
>Siccome sono pigro a scrivere, ho creato delle combobox personalizzate,
>e dei textbox personalizzati

Ok beh certamente con la programmazione ad oggetti, puoi andare a derivare un controllo esistente e personalizzarne il funzionamento o le caratteristiche in base al tuo volere. Quindi un'eventuale logica di business per riempire i parametri di una Stored Procedure la puoi andare a mettere in un controllo derivato oppure in una classe esterna a parte. Insomma ci sono diversi approcci che si possono utilizzare sta a te capire quale è il migliore e come si addice a quello che stai facendo.

>P.S.: Visto che sei un guru, ti faccio una piccola domanda off-thread:

Sono guru solo per il fatto che quel titolo si ottiene sulla base del numero dei messaggi inviati al forum Niente di più. Quindi non vuol dire niente è solo una classificazione per stabilire chi ha partecipato di più al forum.

>ho deciso di impostare le mie applicazioni con SQL server express
>utilizzando esclusivamente SP, faccio bene? ho letto in giro
>che sono + performanti che le semplici istruzioni sql

Certamente sì per innumerevoli motivi. Giro il Thread a Lorenzo che sicuramente ti saprà dire in breve perchè è meglio utilizzarle.

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

lbenaglia Profilo | Guru

>>ho deciso di impostare le mie applicazioni con SQL server express
>>utilizzando esclusivamente SP, faccio bene? ho letto in giro
>>che sono + performanti che le semplici istruzioni sql
>
>Certamente sì per innumerevoli motivi. Giro il Thread a Lorenzo
>che sicuramente ti saprà dire in breve perchè è meglio utilizzarle.

Mi limito a dire la mia solo su questo argomento, dato che quando sento parlare di LINQ mi si rizzano i 4 capelli che mi rimangono in testa
Fai bene ad utilizzare esclusivamente le stored procedure per accedere al DBMS, anzi fai benissimo in quanto offrono diversi vantaggi rispetto alle query "schiantate" nel codice:

- Isolano l'applicazione dalla base dati, quindi permettono di disaccoppiare il sorgente dalla struttura del database. Se occorre effettuare modifiche al db, basterà aggiornare la stored procedure mantenendo invariata la sua interfaccia (parametri di I/O) per fare in modo che il funzionamento dell'applicazione non sia compromesso;

- Offrono performances più elevate, in quanto sono compilate la prima volta che vengono richiamate. Di conseguenza gli step di Parsing, Optimization e Compilation saranno eseguiti solo una volta;

- Possono essere utilizzate per configurare la security del database. In genere gli utenti difficilmente hanno le permission per accedere direttamente alle tabelle base, ma piuttosto si preferisce definire le regole di accesso per ogni categoria di utenti utilizzando viste, UDF e stored procedure.

- Ti mettono al riparo dal pericolosissimo problema del SQL Injection, discusso ampiamente in questo articolo di Ale e David: http://www.dotnethell.it/articles/SQL-Injection-Tutorial-Security.aspx

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

Brainkiller Profilo | Guru

>Mi limito a dire la mia solo su questo argomento, dato che quando
>sento parlare di LINQ mi si rizzano i 4 capelli che mi rimangono
>in testa
>Fai bene ad utilizzare esclusivamente le stored procedure per
>accedere al DBMS, anzi fai benissimo in quanto offrono diversi
>vantaggi rispetto alle query "schiantate" nel codice:

Chiamare una stored procedure tramite LINQ non richiede di schiantare nel codice nessuna query. Sul resto sono d'accordo anche io. La comodità è che invece di definire tutti i relativi parametri è sufficiente richiamare la Stored Procedure in questo modo:

dataContext.NomeSP(parametro1, parametro2, parametro3);

Come dire, una riga di codice invece di 20

Ciao

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

lbenaglia Profilo | Guru

>Chiamare una stored procedure tramite LINQ non richiede di schiantare
>nel codice nessuna query. Sul resto sono d'accordo anche io.
>La comodità è che invece di definire tutti i relativi parametri
>è sufficiente richiamare la Stored Procedure in questo modo:
>
>
>dataContext.NomeSP(parametro1, parametro2, parametro3);
>
>
>Come dire, una riga di codice invece di 20

Convincimi postando una trace catturata col Profiler relativa a quella chiamata

Ciao!
--
Lorenzo Benaglia
Microsoft MVP - SQL Server
http://blogs.dotnethell.it/lorenzo/
http://italy.mvps.org

Brainkiller Profilo | Guru

>Convincimi postando una trace catturata col Profiler relativa
>a quella chiamata

Viene fatto uso della sp_executesql

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

David De Giacomi | Microsoft MVP
http://blogs.dotnethell.it/david/

gabriel81 Profilo | Junior Member

WOW ! Sono inondato dalla vostra conoscenza...

Facciamo una cosa, ora mi studio un idea di come realizzare questa automazione, e poi ve la espongo, così magari mi dite se potrebbe andare bene dal punto di vista delle performance e delle eccezioni possibili...
ok?

come al solito siete dei grandi, grazie 1000

gabriel81 Profilo | Junior Member

Dunque...
Ho elaborato questa soluzione:

Ho creato una classe InterfacciaSQLServer che ospita il metodo:
- CostruisciComandoSqlServer(ByRef ClasseForm As Form, ByVal StoredProcedure As String, ByRef Connessione As SqlConnection) As SqlCommand

Posto il contenuto del metodo, per i posteri che avrano così il codice già bello e pronto.

Il codice sorgente non è stato renderizzato qui
perchè non c'è sufficiente spazio.
Clicca qui per visualizzarlo in una nuova finestra

E' necessario chiamare il controllo (textbox oppure combobox di norma) con lo stesso nome della Proprietà della sp.
Se ad esempio la Stored Procedure deve inserire un nuovo record dentro la tabella "clienti" e vuole i parametri @Nome, @Cognome e @Telefono, chiamerò i controlli textbox Nome,Cognome e Telefono.
Il metedo si và a leggere i parametri della Stored Procedure indicata e per ciascuno cerca sulla classeform indicata il controllo che hanno lo stesso nome.
Carica parametro col relativo valore e direzione.
A questo punto restituisce un comando già parametrizzato e dotato di proprietà "CommandText".

A questo punto basta far eseguire il comando ed il gioco è fatto


Pena: le performance sono leggermente inferiori rispetto alla dichiarazione manuale dei parametri di comando.
Bisogna anche ammettere che il portatile su cui lavoro è un po' vecchiotto, sul mio server, la differenza è non misurabile.

Avete dei pareri/consigli per migliorare la funzione?
Partecipa anche tu! Registrati!
Hai bisogno di aiuto ?
Perchè non ti registri subito?

Dopo esserti registrato potrai chiedere
aiuto sul nostro Forum oppure aiutare gli altri

Consulta le Stanze disponibili.

Registrati ora !
Copyright © dotNetHell.it 2002-2024
Running on Windows Server 2008 R2 Standard, SQL Server 2012 & ASP.NET 3.5