Domanda

Stiamo utilizzando Stored procedure per ogni query nel DB. Questo sembra incredibilmente poco- DRY :

  1. Progetta la tabella
  2. Progetta SP di operazioni CRUD per quella tabella
  3. Codice di progettazione (preferibilmente una classe) per riempire i parametri ed eseguire CRUD SP

Se aggiungiamo una singola colonna o cambiamo un tipo di dati, dobbiamo modificare la tabella, una manciata di SP e una manciata di funzioni in una classe all'interno di .NET.

Quali sono alcuni suggerimenti per ridurre questa duplicazione?

UPDATE:

In combinazione con l'idea di Vinko, ho trovato questo . Ecco un po 'di codice (in C #) che ho ideato per coloro che ne hanno bisogno:

SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["MySQLConnString"].ConnectionString);
SqlCommand comm = new SqlCommand("NameOfStoredProcedure", conn);
comm.CommandType = CommandType.StoredProcedure;

conn.Open();
SqlCommandBuilder.DeriveParameters(comm);
conn.Close();

foreach (SqlParameter param in comm.Parameters)
{ /* do stuff */ }
È stato utile?

Soluzione

Un suggerimento per evitare la modifica di almeno gli SP è quello di scriverli per usare "introspezione", cioè deducendo i nomi delle colonne e i tipi di dati dalle tabelle interne o dalle viste information_schema.

È un codice più complesso da scrivere, ma eviterà di doverlo modificare ogni volta che cambia la tabella e può essere riutilizzato nel resto degli SP.

Crea un singolo SP che descriverà le tabelle per te, ad esempio usando una tabella temporanea (colname varchar, digita varchar) che chiamerai dal resto degli SP.

A proposito, questo può diventare molto complesso e persino irrealizzabile se le tue domande sono complesse, ma d'altra parte, se non lo sono, può farti risparmiare un sacco di problemi.

Altri suggerimenti

Suggerisco di utilizzare uno strumento di generazione del codice, come NetTiers per generare il tuo livello CRUD.

I principi di progettazione OOP si riferiscono al codice procedurale, non al codice dichiarativo. In particolare, il riutilizzo di SP è estremamente problematico.

I design dell'interfaccia utente basati su generatori CRUD sono ben noti. Un altro modo per trasformare esplicitamente gli utenti in impiegati per l'immissione di dati. Se li usi, assicurati di avere un ottimo livello di astrazione tra ciò che producono e ciò con cui gli utenti devono fare i conti.

  

Se aggiungiamo una singola colonna o cambiamo un tipo di dati, dobbiamo modificare la tabella, una manciata di SP e una manciata di funzioni in una classe all'interno di .NET.

Sicuramente sembra che il design del tuo database stia dettando i tuoi requisiti OOP. Inizia invece dall'altra direzione.

Tutti questi approcci di metaquery muoiono nelle loro tracce non appena l'SQL supera una singola tabella. O vuoi una colonna calcolata. Oppure ...

Personalmente, non sono un grande fan di mettere il mio codice di query nelle procedure memorizzate. Con l'eccezione di cose molto complesse, sembra semplicemente eccessivo ridondante.

Ecco come gestisco il mio database e la progettazione di oggetti grezzi:

  1. Creo il modello di dati
  2. Creo una vista per ogni tabella
  3. Creo insert, update, & amp; elimina procs per ogni tabella.
  4. Tutto il mio codice C # punta alle viste e ai proc.

Questo mi permette di:

  1. Avere un target di query altamente flessibile (la vista)
  2. Interrogazione contro le opinioni in qualsiasi modo di cui ho bisogno senza ridondanza.
  3. Impedisci l'accesso diretto alle tabelle tramite la sicurezza del database
  4. Estrarre il modello di dati nel caso in cui avessi mai bisogno di riformattare il modello di dati sottostante senza rompere il mio codice (lo so, questo potrebbe avere costi di prestazione)

Avere una vista che rappresenta la tabella di destinazione probabilmente gestirà molte query e, anche in caso contrario, il peggio che accadrà è che devi creare una vista specifica per la query, che equivale a creare un proc per esso, quindi non c'è nessun lato negativo.

Sento che le persone raccomandano di utilizzare le procedure memorizzate per prevenire gli attacchi SQL Injection, ma se si utilizzano query con parametri durante l'interrogazione della vista, questo non sarà comunque un problema. ... e usiamo sempre query con parametri in ogni modo ... giusto? ; -)

L'approccio 'DeriveParameters' che usi funziona, ma prevede 2 viaggi nel database per ogni richiesta. Ci sarà un impatto sulle prestazioni con questo approccio. La classe SqlHelper del blocco applicazione di accesso ai dati di Microsoft lo mitigherà facendo esattamente la stessa "introspezione", ma facoltativamente memorizzando nella cache i parametri per il riutilizzo. Ciò ti consentirà di creare chiamate SP a linea singola senza ripetizioni "goo" impostazione parametri, ecc.

http://msdn.microsoft.com/en-us/library /cc309504.aspx

Non penso che questo rientri davvero nelle linee guida DRY. Si tratta semplicemente di persistenza, e se stai facendo il n. 3 manualmente, dovresti cercare di adottare uno dei set di strumenti che lo rendono più facile. LINQ to SQL è il mio preferito personale, ma ce ne sono molti.

Anche il tuo # 2 può essere facilmente automatizzato. Ridurre il lavoro complessivo richiesto per 1) progettare il modello di dati (nel concetto) 2) implementarlo a livello di persistenza (creare la tabella o aggiungere la colonna) 3) utilizzarlo a livello di applicazione.

Esistono alcune tabelle che non avranno CRUD e non dovrebbero essere accessibili dall'applicazione e sono artefatti del modello di implementazione del database. In particolare, l'applicazione non dovrebbe accedere alle tabelle dei collegamenti molti-a-molti, ma dovrebbero essere gestite dal database tramite procedure memorizzate.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top