131 messaggi dal 06 giugno 2011
Ciao a tutti, ho un repository generic dove vorreri applicare i filtri a livello db(IQuryable) e non in memoria (IEnumerable), però non capisco perche me li calcola sempre in memoria.

il mio repository è simile a questo:
public abstract class GenericRepository<T> : IGenericRepository<T>
      where T : BaseEntity
   {
       protected DbContext _entities;
       protected readonly IDbSet<T> _dbset;
 
       public GenericRepository(DbContext context)
       {
           _entities = context;
           _dbset = context.Set<T>();
       }
 
       public virtual IEnumerable<T> GetAll()
       {
 
           return _dbset.ToList();
       }
 
       public IEnumerable<T> FindBy(Expression<Func<T, bool>> predicate)
       {
 
           IEnumerable<T> query = _dbset.Where(predicate).ToList(); 
           return query;
       }

      public IQueryable<T> FindBy2(Expression<Func<T, bool>> predicate)
       {
 
           IQueryable<T> query = _dbset.Where(predicate); //errore
           return query;
       }
 
 
       public virtual T Add(T entity)
       {
           return _dbset.Add(entity);
       }
 
       public virtual T Delete(T entity)
       {
           return _dbset.Remove(entity);
       }
 
       public virtual void Edit(T entity)
       {
           _entities.Entry(entity).State = System.Data.Entity.EntityState.Modified;
       }
 
       public virtual void Save()
       {
           _entities.SaveChanges();
       }
   }


quando faccio FindBy mi fa il filtro in memoria se utilizzo FindBy2 mi dice che non posso convertire IEnumerable in IQueryable
Modificato da brux88 il 23 giugno 2016 09.53 -
497 messaggi dal 08 febbraio 2009
Come dici tu la differenza sostanziale sta nel tipo di dati che torni:

IQueryable<T>: Consente di propagare la query fino al DB

IEnumerable<T>: Esegue tutto in memoria (ovvero preleva tutti i dati dal DB e poi li filtra)

Pertanto se il tuo repository espone IEnumerable<T>, di sicuro le operazioni vengono fatte in memoria.
Il fatto che Microsoft abbia reso disponibili degli extension method su IEnumerable<T> in modo da poterci lavorare con LINQ, la sostanza non cambia: essendo IEnumerable il lavoro lo fa la memoria e non il database.

Per quanto riguarda il Find2, invece, il problema è il metodo che stai usando.
EntityFramework per gestire IQueryable in modo corretto ha bisogno di lavorare con degli alberi di espressione che poi ribalta sul DB (andando in dettaglio ha bisogno di una "Expression" e non di una "Func").

Se usi il metodo del DbSet che richiede una func, il tipo restituito è sempre un IEnumerable e non un IQueryable.
131 messaggi dal 06 giugno 2011
grazie per il chiarimento ;)

Torna al forum | Feed RSS

ASPItalia.com non è responsabile per il contenuto dei messaggi presenti su questo servizio, non avendo nessun controllo sui messaggi postati nei propri forum, che rappresentano l'espressione del pensiero degli autori.