Come dovrei implementare il modello di repository per modelli di oggetti complessi?

20

Il nostro modello di dati ha quasi 200 classi che possono essere suddivise in circa una dozzina di aree funzionali. Sarebbe stato bello usare i domini, ma la separazione non è così pulita e non possiamo cambiarla.

Stiamo riprogettando il nostro DAL per utilizzare Entity Framework e la maggior parte delle raccomandazioni che ho visto suggeriscono di utilizzare un pattern di repository. Tuttavia, nessuno degli esempi si occupa veramente di modelli di oggetti complessi. Alcune implementazioni che ho trovato suggeriscono l'uso di un repository per entità. Questo sembra ridicolo e non mantenibile per modelli grandi e complessi.

È davvero necessario creare un UnitOfWork per ogni operazione e un repository per ogni entità? Potrei finire con migliaia di classi. So che questo è irragionevole, ma ho trovato pochissime indicazioni per l'implementazione di Repository, Unit Of Work e Entity Framework su modelli complessi e applicazioni aziendali realistiche.

    
posta Eric Falsken 16.10.2012 - 19:43
fonte

3 risposte

6

In primo luogo, attraverserai tutte le entità che hai e chiediti:

Does it make sense to persist this entity alone?

Ciò che intendo qui, è che nel modello a oggetti, alcune entità sono probabilmente contenute in altre in una relazione principale-dettaglio. Se la tua entità è altamente dipendente da un'altra, non creare un repository per questa entità da solo perché non sarà probabilmente persistere da solo. Invece, creerai un repository per ogni classe genitore, e ti assicurerai che le entità figlio e le altre relazioni siano mantenute allo stesso tempo.

Non mi piace come hanno implementato il pattern di UnitOfWork nel link che hai fornito. Ti suggerisco di fare qualcosa di più seguendo queste linee . Non è necessario definire una classe per repository. La stessa classe può essere utilizzata per ogni repository, ciascuno con la propria istanza della classe UnitOfWork per la durata dell'operazione. È anche possibile riutilizzare lo stesso UnitOfWork in repository diversi per le modifiche che si desidera mantenere allo stesso tempo.

    
risposta data 16.10.2012 - 21:03
fonte
3

Forse dovresti dare un'occhiata a Domain-Driven Design . Si consiglia di raggruppare gli oggetti in Aggregati e creare repository solo per l'entità principale di ciascun aggregato. È un buon modo per portare l'ordine in un modello di un grande oggetto complesso.

Le diverse aree funzionali potrebbero essere Contesti limitati . Esistono varie tecniche per gestire la sovrapposizione di Bounded Contesti se la separazione tra loro non è chiara.

    
risposta data 18.10.2012 - 18:11
fonte
0

Quali fondamenti teorici hai trovato per la progettazione del database "Modello di repository"? Sto indovinando nessuno. È uno strato di complessità che poggia su una premessa fasulla: che il "livello di persistenza" è qualcosa da cui devi essere isolato. Da quello che posso dire, gioca sull'ignoranza diffusa della programmazione dei principi di progettazione relazionale e su una presunta centralità del design OO dell'applicazione. Ma non giustifica la sua esistenza su basi razionali, per non dire teoriche.

La progettazione One True Path to database non è cambiata in 30 anni: analizzare i dati. Trova le chiavi e i vincoli e le relazioni molte-a-uno. Progetta le tue tabelle in base alla forma normale di Boyce-Codd. Utilizzare visualizzazioni e stored procedure per facilitare l'accesso ai dati.

Sebbene non lo sia, un DBMS SQL fornisce un livello di isolamento migliore di quello che può fornire il programmatore. È vero che quando il database cambia, l'SQL utilizzato per accedervi potrebbe dover cambiare. Nota che è vero indipendentemente dal fatto che ci sia o meno un livello di mediazione . Finché l'applicazione utilizza le viste e le stored procedure per accedere al DBMS, gli strumenti di progettazione SQL ordinaria indicheranno quando le modifiche al database sottostante invalidano tali visualizzazioni e stored procedure.

Qui sta la sfida, ovviamente. Uno strato di mediazione fornisce l'illusione dell'isolamento e del conforto al programmatore del codice di scrittura, che sa come fare. L'apprendimento della progettazione di database e SQL richiede l'apprendimento di qualcosa di nuovo. La maggior parte delle persone preferirebbe morire piuttosto che pensare, e molti ci riescono.

Qualcuno del tuo team dubiterà senza dubbio che scrivere SQL per supportare le tue 200 classi richiede molto lavoro. Nessun dubbio. Ma almeno è utile lavoro. Se progettate un database imitando il vostro design OO, farete anche molto lavoro, in gran parte inutile, e sconfiggerete la maggior parte di ciò che vi offre il DBMS.

Ad esempio, si contempla di riflettere l'Unità di lavoro nel database (come presumo una tabella o tabelle). Unità di lavoro è un servizio integrato del DBMS: begin transaction ... aggiornamento database ... commit transaction . Niente da modellare, se non la mappatura delle tue classi alle tabelle del database in SQL.

La tua domanda è stata postata 4 anni fa. Rispondo perché è stato "aggiornato" in qualche modo di recente, a indicare che è ancora di un certo interesse per qualcuno. Spero che la mia risposta incoraggi il lettore ad applicare la teoria relazionale di base al problema invece di adottare una soluzione alternativa.

    
risposta data 02.07.2017 - 23:14
fonte

Leggi altre domande sui tag