Livello dati senza ORM: come lavorarci in modo efficiente?

6

Lavoro su un grande progetto .NET. È iniziato più di 10 anni fa, non c'è ORM (NHibernate o EF intendo) e non vi è alcuna possibilità di migrare ad un ORM molto diffuso (e per query SQL complesse l'ORM non è in alcun modo suite). Utilizziamo il provider MS SQL di ADO.NET con facciata personalizzata per datareader. Costruiamo le query selezionate come stringhe, ad esempio, se abbiamo una query di grandi dimensioni e vogliamo avere alcune personalizzazioni: assomiglia a questo:

public List<SomeEntity> GetEntities(string titleFilter, bool joinsometable, bool selectAll...)

e all'interno di questo metodo abbiamo un generatore di stringhe che costruisce query in base alle condizioni e ai parametri di input. Inoltre, se vogliamo riutilizzare qualche pezzo di SQL (come un elenco di join o condizioni ripetute) li manteniamo come variabili stringa. Quindi alla fine è molto difficile supportarlo. Sono solo curioso: qualcun altro ha problemi simili? Come l'hai risolto?

    
posta mtkachenko 17.12.2016 - 15:45
fonte

5 risposte

3

La mappatura relazionale degli oggetti senza ORM può essere dolorosa e in qualche modo ripetitiva. Un libro non sarebbe sufficiente per affrontare tutti gli aspetti di questo problema e vi assicuriamo che non siete soli in questa situazione.

Capisco dalla tua domanda che sei più interessato alle query complesse. Per questo argomento specifico, puoi prendere in considerazione il modello di progettazione dell'oggetto query . Potrebbe consentire di riutilizzare query SQL complesse. In questo progetto, i criteri sono anche oggetti (composizione) che potrebbero, ad esempio, aiutare a generare le clausole SQL WHERE. Questo risulta essere molto più conveniente da usare rispetto alla generazione dei comandi SQL con concatenazione di stringhe noiose qua e là nel codice.

A questo proposito, posso consigliare vivamente " Modelli di architettura aziendale " di Martin Fowler, che offre begli esempi di questo modello e affronta molti altri punti utili nella tipica applicazione OO con l'integrazione inebriante del database.

    
risposta data 17.12.2016 - 19:55
fonte
2

I'm just curious: does anyone else have such problems?

Sì, li ho anche io. Immagino che chiunque non usi gli ORM, alla fine, passi attraverso la stessa situazione.

How did you solve it?

Evito soluzioni troppo generiche, perché altrimenti corro il rischio di implementare il mio ORM !!

Potresti pensare di dover rendere la tua implementazione il più generica e astratta possibile. Per il bene dei principi SOLIDI. Ed è vero

Tuttavia tieni presente che il tuo obiettivo principale è l'applicazione, non la creazione di un framework durante il processo.

Quindi, l'implementazione di codice riutilizzabile e parametrizzato va bene, ma solo se queste caratteristiche vengono indirizzate in modo appropriato per risolvere i reali bisogni del progetto. Per andare oltre è l'overengineering.

Con il rischio di creare codice meno riusabile, un approccio sta rendendo i DAO meno generici. - I generici, ad un certo livello, sono considerati anche anti-pattern -.

Adattare i DAO alle esigenze dell'azienda è un modo per farlo.

Non c'è bisogno di dire che i componenti degli strati superiori dovrebbero rimanere inconsapevoli di questi problemi. In caso contrario, suggerisco di rivedere il design.

Inoltre, potresti essere interessato alle librerie basate sulla mappatura delle righe. Ad esempio, in java, c'è MyBatis che penso sia disponibile anche per .Net. Non oserei chiamare MyBatis come un ORM come EF o Hibernate, ma come una biblioteca per essere estratto dal database che ha risolto molti dei problemi che potresti subire.

Se non puoi permetterti il costo di integrare più librerie, nel mio progetto attuale, ho implementato l'approccio descritto qui (con alcune personalizzazioni). Funziona come un fascino. Riequilibra la riusabilità e la parametrizzazione.

Sfortunatamente, la Specifica è considerata da alcuni come anti-pattern. Qui il riferimento .

    
risposta data 17.12.2016 - 17:25
fonte
2

Suggerirei di refactoring incrementale del codice usando un micro-ORM come Dapper. È leggero, altamente performante e consente di continuare a utilizzare le istruzioni SQL tradizionali, se è quello che preferisci. Dapper è la mia scelta goto quando non posso usare o non voglio usare qualcosa di più pesante come Entity Framework o Nhibernate.

    
risposta data 18.12.2016 - 00:09
fonte
0

Un modo per farlo è abbracciare completamente SQL, invece di mescolare le tue metafore.

Ad esempio:

var user = context.ExecuteQuery("SELECT * FROM User WHERE UserID = {0}", userID);

Restituisce una raccolta List<User> (contenente un record, in questo caso).

Dapper ed Entity Framework sono entrambi capaci di query come questa. Puoi renderli elaborati come vuoi, eseguire più query e creare oggetti dati complessi in questo modo.

Potresti anche codice generare metodi CRUD, se sei così inclinato.

    
risposta data 17.12.2016 - 19:46
fonte
0

Ho cercato nella proprietà. L'entità avrà molte proprietà. Class PropInt avrà il valore di ritorno e anche come costruire la ricerca. La creazione di una ricerca su Int è la stessa: è sufficiente conoscere il nome della tabella e della colonna.

Utente iEnumerable e DataReader

public iEnumerable<SomeEntity> GetEntities(SomeEntity someEntity);
    
risposta data 18.12.2016 - 13:11
fonte

Leggi altre domande sui tag