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.
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? –
@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
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