2015-09-24 26 views
7

ho un'interfaccia che definisce un repository dal modello Repository:Come richiamare Expression <Func <Entità, bool >> contro una collezione

interface IRepository 
{ 
    List<Customer> GetAllCustomers(Expression<Func<Customer, bool>> expression); 
} 

Ho implementato contro Entity Framework:

class EntityFrameworkRepository 
{ 
    public List<Customer> GetAllCustomers(Expression<Func<Customer, bool>> expression) 
    { 
     return DBContext.Customers.Where(expression).ToList(); 
    } 
} 

che sembra funzionare bene, mi permette di fare qualcosa di simile:

var customers = entityFrameworkRepository.Where(
    customer => String.IsNullOrEmpty(customer.PhoneNumber) 
); 

Ora mi piacerebbe avere un InMemo ryRepository per test e scopi dimostrativi. Ho cercato di crearne uno:

class InMemoryRepository 
{ 
    Dictionary<int, Customer> Customers {get; set;} = new Dictionary<int, Customer>(); 

    public List<Customer> GetAllCustomers(Expression<Func<Customer, bool>> expression) 
    { 
     //what do I put here? 
    } 
} 

Come si può vedere nel codice di cui sopra, stumped su cosa fare per InMemoryRepository.GetAllCustomers attuazione. Cosa devo fare lì per filtrare i clienti in base all'espressione fornita e restituire i risultati?

ho provato:

return Customers.Where(expression)); 

Ma ovviamente è in attesa di un Func<KeyValuePair<int, Customer>, bool> così ottengo un errore di compilazione:

Error CS1929 'Dictionary' does not contain a definition for 'Where' and the best extension method overload 'Queryable.Where(IQueryable, Expression>)' requires a receiver of type 'IQueryable' DataAccess.InMemory

risposta

8

Prova .AsQueryable() metodo:

return Customers.Values.AsQueryable().Where(expression); 
+0

Ho trascorso un'ora su questo, e tu mi hai preso in meno di un minuto. Fantastico. Una correzione rapida, è 'Customers.Values.AsQueryable(). Where (espressione);' – mason

+0

@mason yes, of couse. felice di aiutare! – Backs

-1

Esempio

Expression<Func<Products, bool>> expresionFinal = p => p.Active; 

if (mydate.HasValue) 
{ 
    Expression<Func<Products, bool>> expresionDate = p => (EntityFunctions.TruncateTime(c.CreatedDate) <= mydate); 
    expresionFinal = PredicateBuilder.And(expresionFinal, expresionDate); 
} 

IQueryable<T> query = dbSet; 


    query = query.Where(expresionFinal); 
+0

Non sei sicuro di cosa stai andando qui? L'espressione è già impostata, non posso cambiare la forma. – mason

+0

Avete bisogno di un repository generico come questo: 'public class GenericRepository : IGenericRepository , IDisposable dove T: class {contesto DbContext interno; interno DbSet dbSet; Public GenericRepository (contesto DbContext) { this.context = context; this.dbSet = context.Set (); } pubblico virtuale IEnumerable Get (Expression > Filtro = null) { IQueryable query = dbSet; query = query.Where (filtro); query di ritorno.ToList(); } } ' – J4ime

Problemi correlati