2012-01-23 9 views

risposta

2

modelli repository sono importanti per disaccoppiare il meccanismo di memorizzazione dei dati dall'applicazione. In questo modo è molto più semplice eseguire il test dell'unità o sostituire la struttura dati in un secondo momento. Leggi il mio blogpost su come/perché lo faccio qui: http://blog.staticvoid.co.nz/2011/10/staticvoid-repository-pattern-nuget.html

Personalmente non uso mai più le stored procedure perché non vedo davvero il bisogno per loro nella maggior parte delle circostanze, tuttavia per implementarlo con il mio modello di repository vorrei raccomandare di creare una nuova RepositoryDataSource per mappare la procedura memorizzata e quindi chiamare la procedura memorizzata tramite EF o SQL vecchia scuola. Suggerirei di lanciare un'eccezione di qualche tipo durante l'aggiornamento o il salvataggio.

== EDIT (In risposta alla domanda: 'Perché 2 strati') ==

La ragione per cui ho scelto di andare per due livelli è perché nella mia mente un repository è allo stesso tempo a che fare con il modo di ottenere i dati (il livello dell'origine dati) e il modo in cui si presenta il livello (nella mia implementazione, forse repository con un nome errato). Dividendo l'implementazione a metà di come può rimanere uguale indipendentemente dal cosa. viceversa se vuoi cambiare il modo in cui puoi farlo rimanendo solo vagamente accoppiati al cosa.

Ad esempio, è possibile scambiare l'origine dati EF con una versione in memoria. Questo non dovrebbe necessariamente cambiare il modo in cui i dati vengono presentati all'applicazione.

Dall'altro lato si consiglia di memorizzare i dati nella cache o di accedere alcune informazioni sulle prestazioni delle scritture all'archivio dati. Perché dovrebbe importare quale meccanismo di archiviazione effettivo viene utilizzato sotto le coperture?

Personalmente ho trovato la suddivisione in questo particolare luogo per rendere la soluzione molto più flessibile.

+1

EF non è già un'astrazione sul tuo spazio di archiviazione? Perché hai bisogno di avvolgerlo ancora una volta? Che cosa esattamente test unitario in un repository? –

+0

@EstebanAraya - generalmente non si analizzano i repository (test di integrazione li test). Con l'iniezione di un'interfaccia di repository è possibile prendere in giro l'analisi di altre classi (business logic) indipendentemente da un database. La simulazione può restituire qualsiasi raccolta di POCO necessaria ai test. – TrueWill

+0

EF è un'astrazione che fornisce la mappatura di oggetti, il rilevamento di entità/cambiamento. Il repository include la logica di business utilizzata per accedere ai dati. La logica è stata descritta nella risposta di @ Eranga. interrogando i prodotti ma escludendo i prodotti fuori produzione. Utilizzando il modello di repository, si garantisce che le regole aziendali vengano sempre rispettate quando si accede ai dati sottostanti. – BZink

14

Penso che abbiate perso un punto sul motivo per cui le persone implementano pattern di repository quando EF già implementa pattern di repository tramite ObjectSet/DbSet?

La risposta popolare sarebbe perché molti tutorial ti consigliano di usarlo senza giustificare i motivi. Esistono validi motivi per non utilizzare il livello di repository su ObjectSet/DbSet. Comunque indicherò alcune ragioni sul perché è preferibile.

Filtri predefiniti Ci sono molte situazioni nelle applicazioni della vita reale in cui è necessario un filtro predefinito. Ad esempio i prodotti fuori produzione non sono venduti. Se esponi i Prodotti ObjectSet/DbSet direttamente ci saranno problemi se qualcuno ha dimenticato di applicare il filtro predefinito. Evita anche la duplicazione della logica. È inoltre possibile modificare il filtro predefinito in un secondo momento senza causare problemi.

public IQueriable<Product> GetAll() 
{ 
    return context.Products.Where(p => !p.IsDiscontinued); 
} 

morbida Elimina Molte applicazioni utilizzano eliminazioni morbidi in cui si mantiene una colonna come IsDeleted senza realmente rimuovere la riga.Ora ObjectSet/DbSet ha un metodo Delete ma una volta chiamato questo metodo assegnerà i valori null alle proprietà FK Nullabili. Potresti non volerlo.

public void Delete(Product product) 
{ 
    // can apply any other logic here 
    product.IsDeleted = true; 
} 

solo leggere Enti Ci sono molte situazioni in cui qualche altra applicazione è responsabile della creazione, l'eliminazione e l'aggiornamento entità e la vostra applicazione viene visualizzata solo l'entità. Ma in questo caso ObjectSet/DbSet espone funzionalità non supportate. Un altro vantaggio in questo caso sarebbe quello di utilizzare l'opzione NoTracking per ridurre il tempo di materializzazione dell'entità.

Cambia accesso ai dati senza esporre l'implementazione In alcuni casi LINQ non è sufficiente. Qui puoi usare raw SQL o SP. Avere un repository eviterà di esporre diversi metodi di interrogazione/aggiornamento quando la funzionalità esposta da EF non è sufficiente.

Utilizzo di database esistenti Quando non si ha il lusso di creare il database che EF è in grado di gestire. La tabella esistente può avere colonne Sql Variant, XML. Duplicazione di voci in altre tabelle e innumerevoli altri casi che è necessario gestire per mantenere l'integrità del database.

Queste tecniche potrebbero non essere a prova di proiettile, ma saranno utili se la situazione lo richiede. Quello che suggerirei è senza passare direttamente agli archivi a cui pensate meglio aggiunge un altro livello di astrazione necessario per implementare le funzionalità richieste.

Problemi correlati