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


21

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

Stiamo ridisegnando il nostro DAL per utilizzare Entity Framework e la maggior parte dei consigli che ho visto suggeriscono di utilizzare un modello di repository. Tuttavia, nessuno dei campioni ha a che fare con 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 lezioni. So che questo è irragionevole, ma ho trovato poche indicazioni sull'implementazione di repository, unità di lavoro ed Entity Framework su modelli complessi e applicazioni aziendali realistiche.

Risposte:


6

Innanzitutto, esaminerai tutte le entità che hai e ti chiederai:

Ha senso persistere da solo questa entità?

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

Non mi piace come hanno implementato il modello UnitOfWork nel link che hai fornito. Ti consiglio di fare qualcosa di più in questo senso . Non è necessario definire una classe per repository. La stessa classe può essere utilizzata per ogni repository, ognuno con la propria istanza della classe UnitOfWork per la durata dell'operazione. È inoltre possibile riutilizzare la stessa UnitOfWork in repository diversi per le modifiche che si desidera vengano mantenute contemporaneamente.


Bel link! Lo sto provando.
Eric Falsken,

Il tuo link (e la risposta) sono stati i più utili, anche se ho finito per non usare gli schemi forniti. Ho finito per usare una classe wrapper che inoltrava i metodi Aggiungi / Allega / Rimuovi / Salva modifiche per funzionare come un archivio generico, quindi ho aggiunto un metodo Query / QuerySingle / QueryAll che accetta le classi di query personalizzate per contenere la mia implementazione delle query. Questo sta funzionando bene in modo che io possa fare entrambe le query LINQ e T-SQL senza coinvolgere direttamente EF.
Eric Falsken,

Entity Framework, con il suo utilizzo di transazioni, è già un'implementazione del modello Unit of Work.
Greg Burghardt,

1
il collegamento è morto ...
Newtopian,

3

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

Le diverse aree funzionali potrebbero essere contesti limitati . Esistono varie tecniche per gestire i contesti limitati sovrapposti se la separazione tra loro non è chiara.


0

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

L'unico vero percorso per la progettazione del database non è cambiato da 30 anni: analizzare i dati. Trova le chiavi, i vincoli e le relazioni molti-a-uno. Progetta i tuoi tavoli secondo la forma normale di Boyce-Codd. Utilizzare le viste e le procedure memorizzate per facilitare l'accesso ai dati.

Per quanto non sia amato, un DBMS SQL offre un livello di isolamento migliore di qualsiasi cosa il programmatore possa fornire. È vero che, quando il database cambia, potrebbe essere necessario modificare l'SQL utilizzato per accedervi. Ma nota che questo è vero indipendentemente dal fatto che ci sia o meno un livello di mediazione . Finché l'applicazione utilizza viste e procedure memorizzate per accedere al DBMS, i normali strumenti di ingegneria SQL indicheranno quando le modifiche al database sottostante invalidano tali viste e procedure memorizzate.

Qui sta la sfida, ovviamente. Uno strato di mediazione fornisce l'illusione dell'isolamento e il conforto al programmatore di scrivere codice, che lui sa come fare. L'apprendimento della progettazione di database e SQL richiede l'apprendimento di qualcosa di nuovo. Molte persone preferiscono morire piuttosto che pensare, e molti ci riescono.

Qualcuno del tuo team obietterà senza dubbio che scrivere SQL per supportare le tue 200 classi richiede molto lavoro. Nessun dubbio. Ma almeno è un lavoro utile . Se si progetta un database imitando il proprio progetto OO, si farà anche molto lavoro, in gran parte inutile, e si sconfiggerà la maggior parte di ciò che offre il DBMS.

Ad esempio, si considera l'Unità di lavoro che riflette nel database (come tabella o tabelle, presumo). Unità di lavoro è un built-in servizio del DBMS: begin transaction... aggiornamento del database ... commit transaction. Nulla da modellare, tranne la mappatura delle classi alle tabelle del database in SQL.

La tua domanda è stata pubblicata 4 anni fa. Sto rispondendo perché è stato "aggiornato" in qualche modo di recente, indicando che è ancora interessante per qualcuno. Spero che la mia risposta incoraggi il lettore ad applicare la teoria relazionale di base al problema invece di adottare una soluzione inutile.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.