Come suggerire l'uso di un ORM invece delle stored procedure?

29

Lavoro in un'azienda che utilizza solo stored procedure per l'accesso a tutti i dati, il che rende molto fastidioso mantenere sincronizzati i nostri database locali come ogni commit che abbiamo per eseguire nuovi proc. Ho usato alcuni ORM di base in passato e trovo l'esperienza molto migliore e più pulita. Vorrei suggerire al responsabile dello sviluppo e al resto del team che esamineremo l'utilizzo di un ORM di qualche tipo per lo sviluppo futuro (il resto del team conosce solo le stored procedure e non ha mai usato altro). L'architettura attuale è .NET 3.5 scritta come .NET 1.1, con "divinità" che usano una strana implementazione di ActiveRecord e restituiscono DataSet non tipizzati che sono collegati in loop in file code-behind - le classi funzionano in questo modo:

class Foo { 
    public bool LoadFoo() { 
        bool blnResult = false;
        if (this.FooID == 0) { 
            throw new Exception("FooID must be set before calling this method.");
        }

        DataSet ds = // ... call to Sproc
        if (ds.Tables[0].Rows.Count > 0) { 
            foo.FooName = ds.Tables[0].Rows[0]["FooName"].ToString();
            // other properties set
            blnResult = true;
        }
        return blnResult;
    }
}

// Consumer
Foo foo = new Foo();
foo.FooID = 1234;
foo.LoadFoo();
// do stuff with foo...

Non c'è praticamente nessuna applicazione di nessun modello di design. Non ci sono test di sorta (nessun altro sa come scrivere test unitari, e il test viene eseguito caricando manualmente il sito Web e scorrendo). Guardando attraverso il nostro database abbiamo: 199 tabelle, 13 viste, un enorme 926 stored procedure e 93 funzioni. Circa 30 tabelle vengono utilizzate per lavori batch o esterni, il resto viene utilizzato nella nostra applicazione principale.

Vale la pena perseguire un approccio diverso in questo scenario? Sto parlando di andare avanti solo perché non siamo autorizzati a rifattorizzare il codice esistente poiché "funziona", quindi non possiamo cambiare le classi esistenti per usare un ORM, ma non so quanto spesso aggiungiamo moduli nuovi di zecca di aggiungere / correggere i moduli correnti quindi non sono sicuro che un ORM sia l'approccio giusto (troppo investito nelle stored procedure e nei DataSet). Se è la scelta giusta, come dovrei presentare il caso per l'utilizzo di uno? Al di sopra della mia testa gli unici benefici che posso pensare è avere un codice più pulito (anche se potrebbe non esserlo, dato che l'architettura attuale non è costruita con gli ORM in mente quindi dovremmo fondamentalmente fare il montaggio della giurisprudenza su moduli futuri ma i vecchi continuerebbero a utilizzare i DataSet) e meno problemi a ricordare quale script di procedura è stato eseguito e quali devono essere eseguiti, ecc. ma questo è tutto, e non so quanto sarebbe convincente un argomento. La manutenibilità è un'altra preoccupazione ma una che nessuno tranne me sembra preoccuparsi.

    
posta Wayne Molina 11.05.2011 - 16:12
fonte

7 risposte

44

Le stored procedure sono sbagliate, sono spesso lente e approssimativamente efficienti come il normale codice client.

[L'accelerazione è solitamente dovuta al modo in cui il client e all'interfaccia della stored procedure sono progettati e al modo in cui le transazioni vengono scritte come burst brevi e mirati di SQL.]

Le stored procedure sono uno dei peggiori posti in cui inserire il codice. Rompe la tua applicazione in due lingue e piattaforme in base a regole spesso casuali.

[Questa domanda sarà downvoted per avere un punteggio di circa -30 perché molte, molte persone sentono che le stored procedure hanno poteri magici e devono essere usate nonostante i problemi che causano.]

Lo spostamento di tutto il codice di procedura memorizzato nel client renderà le cose molto più semplici per tutti.

Dovrai comunque aggiornare lo schema e il modello ORM di volta in volta. Tuttavia, le modifiche dello schema sono isolate dalle modifiche ORM, consentendo una certa indipendenza tra le applicazioni e lo schema del database.

Sarai in grado di testare, correggere, manutenere, comprendere e adattare tutte quelle stored procedure mentre le riscrivi. La tua app funzionerà più o meno allo stesso modo e diventerà molto meno fragile perché non stai più introducendo in due tecnologie diverse.

Gli ORM non sono magici e le buone capacità di progettazione del database sono assolutamente essenziali per farlo funzionare.

Inoltre, i programmi con un sacco di SQL client possono rallentare a causa della scarsa considerazione sui limiti delle transazioni. Uno dei motivi per cui le stored procedure sembrano essere veloci è che le stored procedure impongono un design molto accurato delle transazioni.

Gli ORM non impongono magicamente un'accurata progettazione delle transazioni. La progettazione delle transazioni deve ancora essere eseguita con la stessa cura con cui si scriveva le stored procedure.

    
risposta data 11.05.2011 - 17:34
fonte
19

Le stored procedure sono buone, veloci e molto efficienti e sono il posto ideale dove inserire il codice relativo ai dati. Spostare tutto quel codice sul client renderà le cose leggermente più semplici per te come sviluppatore client (leggermente, dato che dovrai ancora aggiornare lo schema e il modello ORM quando il commit le modifica) ma perderai tutto quel codice esistente e farai la tua app è più lenta e probabilmente più fragile considerando la perdita di tutte quelle capacità di sql.

Mi chiedo se gli amministratori di database stiano seduti lì dicendo "oh, ogni commit, devo buttar giù il client da capo, dovremmo invece spostare tutto il codice in moduli DB".

Nel tuo caso, dovresti essere in grado di sostituire l'ORM personalizzato esistente (ad esempio le tue classi divertenti) con qualcun altro senza alcuna perdita, tranne le modifiche al modo in cui il codice code-behind viene scritto. Puoi mantenere gli SP anche perché la maggior parte (tutti?) Degli ORM li chiamerà felicemente. Quindi, consiglierei di sostituire quelle classi "Foo" con un ORM e di andare da lì. Non consiglierei di sostituire i tuoi SP.

PS. Sembra che tu abbia un sacco di codice comune nelle classi code-behind, che li rende un modello di progettazione in sé. cosa pensi che un modello di design è in primo luogo! (ok, potrebbe non essere il migliore, o anche uno buono, ma è ancora un DP)

Modifica: e ora con Dapper , qualsiasi motivo per evitare sprocs su un ORM pesante è andato.

    
risposta data 11.05.2011 - 17:25
fonte
11

Sembra che tu stia cercando di guidare la tua squadra da un estremo (stored procedure e set di dati) a un altro (un ORM in piena regola). Penso che ci siano altre modifiche aggiuntive che puoi impostare sull'implementazione per migliorare la qualità del codice del tuo livello di accesso ai dati, che il tuo team potrebbe essere più disposto ad accettare.

Il codice di implementazione del record attivo a metà forno che hai pubblicato non è particolarmente elegante: ti consiglio di fare ricerche sul Pattern del repository che è facile da capire e implementare ed è molto popolare con gli sviluppatori .NET. Questo pattern è spesso associato a quello di ORM, ma è altrettanto facile creare repository usando semplicemente ADO.NET.

Per quanto riguarda DataSet - schifo! Le tue librerie di classi saranno molto più facili da utilizzare se si restituiscono oggetti tipizzati staticamente (o anche dinamici). Credo che questa illustrazione spieghi la mia opinione su DataSet meglio di quanto potrei.

Inoltre, puoi abbandonare i proc memorizzati senza saltare a un ORM: non c'è niente di sbagliato nell'usare l'SQL parametrizzato. In effetti, la preferirei sicuramente usando i proc memorizzati a meno che non si abbiano procedure complesse che salvano su più round trip sul server. Anch'io lo odio quando apro un database precedente e vedo un elenco infinito di procedure CRUD.

Non sto scoraggiando l'uso degli ORM - generalmente li uso sulla maggior parte dei progetti su cui lavoro. Tuttavia posso capire perché ci potrebbe essere un sacco di attriti nel tentativo di introdurre uno in questo progetto e il tuo team che, per dirla in modo gentile, sembrano aver smesso di imparare cose nuove circa 8 anni fa. Detto questo, darei sicuramente un'occhiata alla nuova generazione di "Micro ORM" come Dapper (usato per alimentare questo sito non meno) e Massive , entrambi incredibilmente facili da usare e ti avvicinano all'SQL di un tipico ORM, e che il tuo team potrebbe essere più disposto ad accettare.

    
risposta data 12.05.2011 - 00:13
fonte
4

Sono in una situazione simile, in realtà il nostro hardware, il potere e la politica si appoggiano al lato del database, quindi tutto passa attraverso una stored procedure. Sfortunatamente, sono un problema per un programmatore, specialmente quando si tratta di metadati e generazione di codice, poiché non ci sono dati meta ricchi nelle stored procedure come tabelle.

Indipendentemente da ciò, è comunque possibile scrivere codice elegante e pulito utilizzando i proc memorizzati. Attualmente sto implementando il pattern Repository con tutte le stored procedure. Ti suggerisco di guardare FluentAdo.net per la sua brillante idea quando esegui il mapping da datareader ai tuoi oggetti di business. Ho preso un pezzo di quell'idea e l'ho riproposto per la mia soluzione di casa.

    
risposta data 06.03.2013 - 20:30
fonte
3

JFTR - Sono uno sviluppatore PHP modesto, ma mi sembra un problema prevalentemente politico.

Data la scala del "rot" che supporta l'app, quindi - le migliori pratiche a parte - ci sarebbe un overhead significativo per eliminarlo. Sembra che sia al confine con il territorio della riscrittura.

Potete garantire che l'alternativa che suggerite potrebbe produrre benefici per giustificare il costo per l'azienda? Sospetto che il ROI di questa impresa possa essere difficile da vendere al business. A meno che l'app non sia instabile o se tu possa dimostrare il merito della revisione in termini finanziari, ciò potrebbe rivelarsi difficile.

ORM è l'alternativa solo a SPROCS? Ci sono un paio di modelli di progettazione tra un ORM completo e un SQL vaniglia. Forse potresti iniziare il processo portando questi SPROCS gradualmente fuori dal DB in un DBAL. C'è il pericolo, naturalmente, che questo si trasformi in un ORM homebrew nel tempo - ma avresti ottenuto un passo avanti verso l'obiettivo.

    
risposta data 11.05.2011 - 23:32
fonte
2

Siamo passati da SP a ORM qualche anno fa.

In un caso abbiamo dovuto aggiornare 80 tabelle. Il vecchio modello di stima avrebbe stimato 80 ore per questo con entlib e SP. L'abbiamo fatto in 10:)

Ci ha concesso una riduzione dell'80% del tempo impiegato per lo sviluppo del livello di accesso ai dati.

    
risposta data 12.05.2011 - 11:07
fonte
-1

Sembra più che il problema di fondo sia che le tue implementazioni non funzionano correttamente e automaticamente.

Potrebbe essere più semplice impostare un motore di compilazione continuo che sappia come manipolare i database come necessario dopo ogni commit.

    
risposta data 12.05.2011 - 11:12
fonte

Leggi altre domande sui tag