2009-02-06 9 views
18

Sto iniziando un nuovo progetto e ho deciso di provare a incorporare i modelli DDD e includere anche Linq alle entità. Quando guardo l'ObjectContext dell'EF sembra che stia svolgendo le funzioni sia del Repository che dell'Unità di Lavoro:Entity Framework as Repository e UnitOfWork?

Repository nel senso che l'interfaccia del livello dati sottostante è astratta dalla rappresentazione dell'entità e posso richiedere e salvare i dati attraverso l'ObjectContext.

Unità di lavoro nel senso che posso scrivere tutti i miei inserti/aggiornamenti nell'oggettoContext ed eseguirli tutti in un colpo solo quando faccio un SaveChanges().

Sembra superfluo mettere un altro livello di questi modelli sopra EF ObjectContext? Sembra anche che le classi Model possano essere incorporate direttamente sopra le entità generate da EF usando 'partial class'.

Sono nuovo al DDD quindi per favore fatemi sapere se mi manca qualcosa qui.

risposta

17

Non sembra che Entity Framework è una buona implementazione di Repository, perché:

  • Il contesto oggetto è sufficientemente astratto fare bene unit test di cose che fanno riferimento, in quanto è vincolata al l'accesso al DB. Avere un riferimento IRepository invece funziona molto meglio per creare test unitari.
  • Quando un client ha accesso a ObjectContext, il client può fare praticamente tutto ciò che gli interessa. L'unico vero controllo che hai su tutto questo è rendere privati ​​determinati tipi o proprietà. È difficile implementare una buona sicurezza dei dati in questo modo.
  • Su un modello non banale, ObjectContext non è sufficientemente astratto. Ad esempio, è possibile avere sia tabelle che stored procedure associate allo stesso tipo di entità. Non si vuole veramente che il client debba distinguere tra i due mapping.
  • Su una nota correlata, è difficile scrivere regole aziendali complete e ben applicate e codice entità. In effetti, è discutibile se questa sia o meno una buona idea.

D'altra parte, una volta che si dispone di un ObjectContext, l'attuazione del Pattern Repository è banale. In effetti, per i casi che non sono particolarmente complessi, il Repository è qualcosa di un wrapper attorno ai tipi ObjectContext e Entity.

+2

Grazie Craig. Ho trovato un codice in un blog di Simon Segal su http://www.simonsegal.net/blog/2009/01/13/entity-framework-repository-specifications-and-fetching-strategies/ che fornisce alcuni esempi di implementazione del repository per Entity Framework. – Weej

+0

Attualmente stai utilizzando EntityFramework nei tuoi progetti? C'è qualche difficoltà nell'implementazione? Grazie ancora – Weej

+0

Sì, stiamo utilizzando Entity Framework. Non vi è alcuna difficoltà nell'implementazione del repository; è banale Abbiamo tutti i tipi di difficoltà con lo stesso Entity Framework; Penso che questo sia probabilmente vero per qualsiasi ORM. –

7

Direi che dovresti guardare l'ObjectContext come UnitOfWork, e non come un repository.

Un ObjectContext non può essere un repository -imho- poiché è "generico". Dovresti creare i tuoi repository, che hanno metodi specializzati (come GetCustomersWithGoldStatus per esempio) accanto ai normali metodi CRUD.

Quindi, cosa farei, è creare repository (uno per ogni radice aggregata) e lasciare che questi repository utilizzino ObjectContext.

+0

Grazie per i commenti Frederik. Implementeresti GetCustomersWithGoldStatus direttamente nel repository? Hai preso in considerazione l'utilizzo dei metodi di estensione? Pensi che i metodi di estensione abbiano un posto in questo scenario? – Weej

+0

Su quale tipo creerai un metodo di estensione simile? Effettivamente lo creo sul repository, ma non come un metodo di estensione. Il repository può essere considerato come "la raccolta" da cui si ricevono entità, quindi penso che sia un posto valido per farlo in questo modo –

0

mi piace avere un livello di repository per i seguenti motivi:

EF di Gotcha

Quando si guarda ad alcuni dei tutorial attuali EF (codice prima versione), è evidente c'è una numero di getcha da gestire, in particolare attorno a grafici oggetto (entità contenenti entità) e scenari disconnessi. Penso che un livello di repository sia ottimo per avvolgerli in un unico posto.

Una chiara di meccanismi di accesso dati

Un repository fornisce un quadro specifico di come la BL accede e aggiorna l'archivio dati. Espone metodi che hanno un unico scopo chiaro e possono essere testati indipendentemente dal BL. Esempio standard dai libri di testo, Trova() per trovare una singola entità. Un esempio più specifico dell'applicazione, Clear() per cancellare una tabella db.

Un posto per ottimizzazioni

Inevitabilmente si arriva contro colpi di prestazioni quando si usano EF vaniglia. Io uso il repository per nascondere i meccanismi di ottimizzazione dal BL.

Esempi,

getKeys() per proiettare le chiavi memorizzate nella cache delle tabelle (per le decisioni/Aggiorna Insert). La lettura della chiave è più veloce e utilizza meno memoria rispetto alla lettura dell'entità completa.

Caricamento cumulativo tramite SqlBulkCopy. EF inserirà le singole istruzioni SQL. Se si desidera che una singola istruzione inserisca più righe, SqlBulkCopy è un buon meccanismo. Il repository incapsula questo e fornisce i metadati per SqlBulkCopy. Oltre al metodo Insert, è necessario un metodo StartBatch() e EndBatch(), che è anche un argomento per un layer UnitOfWork.

Problemi correlati