2011-08-05 12 views
7

Lasciatemi dire, sono giunto alla conclusione (dopo un lungo periodo di prova) che l'Unità di lavoro del repository & quando si utilizza Entity Framework è semplicemente sbagliata, errata, errata e this says why.Interrogazione riutilizzabile in Entity Framework SENZA repository. Come?

Ma io odio davvero quelle query incorporate. La domanda è, dove posso metterli invece se sono così contro un repository, ecc? (risposte pulite solo per favore, esempi molto apprezzati).

Ho appena imbucato due progetti contenenti i miei repository, unità di lavoro e interfacce con centinaia di di file perché il payback non si vedeva da nessuna parte. Penso che molte persone, incluso me stesso, siano saltate sul carrozzone del Repository perché è quello che stavano facendo gli altri, ma a posteriori, penso che sia davvero una corsa verso il nulla.

/sospirare

Richard

risposta

3

Dove si aspetta di metterli? Hai solo poche scelte:

  1. servano da dove si trovano e utilizzano metodi di estensione personalizzati, query views, viste di database mappati o personalizzato defining queries per definire parti riutilizzabili
  2. Esporre ogni singola query come metodo su una classe separata. Il metodo non deve esporre IQueryable e non deve accettare Expression come parametro = l'intera logica di query deve essere racchiusa nel metodo. Ma questo renderà la tua classe coprendo i metodi correlati molto come repository (l'unico che può essere deriso o simulato). Questa implementazione è vicina all'implementazione utilizzata con le stored procedure.
  3. Si procederà come nel metodo precedente ma invece di inserire query in una classe separata, le imposteranno come metodi statici direttamente all'entità. Questo è molto più difficile da testare perché i metodi statici non possono essere sostituiti con il mocking (richiede un framework di test più complesso). Questo fa parte di active record pattern in cui ogni entità è responsabile del caricamento e del salvataggio nel database.

Esempio di metodo di estensione personalizzata:

public static IQueryable<TEntity> GetByName(this IQueryalbe<TEntity> query, string name) 
    where TEntity : IEntityWithName 
{ 
    return query.Where(e => e.Name == name); 
} 

Esempio di metodi di classe personalizzata che espongono:

public class QueryProvider 
{ 
    public QueryProvider() {} 

    public IEnumerable<TEntity> GetByName(IYourContext context, string name) 
     where TEntity : IEntityWithName 
    { 
     return context.CreateObjectSet<TEntity>().Where(e => e.Name == name).ToList(); 
    } 
} 
+0

Entity Framework & Testing sono quasi un ossimoro a mio avviso ma so cosa intendi. Non appena le cose si complicano, gli approcci di cui sopra cadono a pezzi ma come dici tu, che altro c'è?Avvolgere tutto in un repository sta solo spostando la colpa da qualche altra parte. – Richard

2

Build Reusable, Testable Queries Part 1

Questo è un post sul blog ho scritto circa la costruzione di query riutilizzabili. L'utilizzo dei metodi di estensione consente di creare query componibili.

utilizzando un modello come il modello di specifica può aiutare a creare query che possono essere riutilizzati o salvati (serializzati). Inoltre, se disponi di un sistema a doppia entrata, puoi eseguire la stessa istanza di query su due diversi database.

il seguente esempio non utilizza EF ma sostituisce l'IEnumerable con un contesto EF e ottieni ciò che stai cercando. i parametri vengono passati attraverso il costruttore.

public class PartialMatchQuery : IModelQuery<string, IEnumerable<string>> 
{ 
    private readonly string partial; 

    public PartialMatchQuery(string partialString) 
    { 
     partial = partialString; 
    } 

    public IEnumerable<string> Execute(IEnumerable<string> model) 
    { 
     return model.Where(s => s.ToLower().Contains(partial)); 
    } 
} 
Problemi correlati