2012-02-14 24 views
8

Spesso vedo segni di esempio repository che assomigliano a questo:Repository modello - troppi metodi

public interface IRepository<T> 
{ 
    T GetById(int id); 
    IEnumerable<T> GetAllByName(string name); 
} 

Ma come si fa a gestire i casi in cui può essere necessario fare una ricerca complessa? Non credo che sarebbe una buona idea aggiungere molti metodi per l'interfaccia che lo renderebbero finiscono per assomigliare:

IEnumerable<T> GetAllByFirstName(string name); 
IEnumerable<T> GetAllByLastName(string name); 
IEnumerable<T> GetAllByFirstAndLastName(string name); 
IEnumerable<T> GetAllByAddress(string name); 
... 
... 
... 

risposta

6

Utilizzare il Predicate Builder per costruire dinamicamente la cui condizione di

public interface IRepository<T> 
{ 
    T GetById(int id); 

    IEnumerable<T> GetAllBy(Expression<Func<T, bool>> predicate); 
} 

Poi costruire la condizioni

var predicate = PredicateBuilder.True<Customer>(); 
    if (!string.IsNullOrEmpty(FirstName)) 
    { 
     predicate = predicate.And(d => d.FirstName.Contains(FirstName)); 
    } 

    if (!string.IsNullOrEmpty(LastName)) 
    { 
     predicate = predicate.And(d => d.LastName.Contains(LastName)); 
    } 

    var products = productRepo.GetAllBy(predicate); 

Creare una classe per superare i criteri di ricerca

public class CustomerFilterCriteria 
{ 
    public string FirstName { get; set; } 

    public string LastName { get; set; } 

    public string Address { get; set; } 

} 

public interface IRepository<T> 
{ 
    T GetById(int id); 
    IEnumerable<T> GetAllBy(CustomerFilterCriteria criteria); 
} 
+1

Cosa se non posso usare le espressioni? Ad esempio, se devo utilizzare stored procedure dietro il repository? – Books

+0

@Ashley Vedere la risposta modificata – Eranga

+0

Queste funzionalità sono state incorporate in linq poiché questa risposta è stata pubblicata? –

0

si potrebbe aggiungere un filtermodel e verificare quali filtri sono stati riempiti in questo modo:

IEnumerable<T> GetAllByFiilter(FilterModel filter); 


public class FilterModel { 
    public string Lastname {get;set;} 
    public string Firstname {get;set;} 
} 


public IEnumerable<T> GetAllByFilter(FilterModel filter) { 
    if(!string.IsNullOrWhiteSpace(filter.Lastname) { 
    //add restriction 
    } 
    // .. etc .. 
} 
0

"Get metodo" potrebbe essere un'interfaccia a sé stante:

public interface IGetMethod<T> 
    { 
     IEnumerable<T> get(String name); 
    } 

    class GetByName<T> : IGetMethod<T> 
    { 
     IEnumerable<T> get(String name) 
     { 
      // ... 
     } 
    } 

    public interface IRepository<T> 
    { 

     IEnumerable<T> GetAllByMethod(IGetMethod<T> method, string name); 
    } 
2

domanda: Perché fare il repository generico, se avete intenzione di essere esporre metodi specifici di tipo (o fare tutto il le entità hanno FirstName, LastName, Indirizzo etc?).

Se le risorse di dati sottostanti sono albero di espressioni LINQ abilitato, una firma comune sarebbe anche generica, ad es.

IEnumerable<TEntity> Query(Expression<Func<TEntity, Boolean>> filter) 

e se volete le vostre domande a essere 'impilabile', si potrebbe esporre un IQueryable

IQueryable<TEntity> Query(Expression<Func<TEntity, Boolean>> filter) 
1

Heres metodi posso fornire il mio modello di repository,

public interface IRepository<T> : IDisposable 
    { 
     void Create(T entity); 

     void Delete(T entity); 

     void Update(T entity); 

     IQueryable<T> GetAll(); 

     T GetBy(Expression<Func<T, bool>> predicate, params Expression<Func<T, object>>[] includes); 
    } 

Personalmente ritengo che la sua migliore per consentire una query in seguito come a volte è necessario mi piace anche avere un getby generico. La combinazione di questo è che tutti i miei repository tipizzati sono forniti genericamente senza alcuna configurazione di entità singola.

Leggi il mio articolo su su di esso qui http://blog.staticvoid.co.nz/2011/10/staticvoid-repository-pattern-nuget.html

0

avere un repository generico

public interface IRepository<T> 
{ 
    T GetById(int id); 
    IEnumerable<T> GetAllBy(Expression<Func<T, bool>> predicate); 
} 

poi hanno repository più specifici

public interface IUserRepository : IRepository<T> 
    { 
     User GetByName(string name); 
    } 

In questo modo il repository generico gestisce tutte le cose CRUD e i tuoi depositi attuali nulla