开发者

How many objects in my memory with Take extension method in EF?

I use a GenericRepository which has the Get method :

I would like to know if there is a loading difference between following chunks of code:

Expression<Func<PressRelease_ar, bool>> exp = p => p.Id <=5 ; 
lst = Global.uow.PressReleaseRepository_ar
      .Get
      (
         filter : exp, 
         orderBy: n => n.OrderByDescending(d => d.Id)
       ).ToList();

And

 lst = Global.uow.PressReleaseRepository_ar
          .Get
          (
             orderBy: n => n.OrderByDescending(d => d.Id)
          ).Take(5).ToList();

For more details, this is the Get method:

    public virtual IEnumerable<TEntity> Get(
                                 Expression<Func<TEntity, bool>> filter = nu开发者_JS百科ll,
                                 Func<IQueryable<TEntity>,
                                 IOrderedQueryable<TEntity>> orderBy = null,
                                 string includeProperties = "")
   {

      IQueryable<TEntity> query = dbSet;

      if (filter != null) query = query.Where(filter);

      foreach (var includeProperty in includeProperties.Split
                 (new char[] { ',' }, StringSplitOptions.RemoveEmptyEntries))
      {
          query = query.Include(includeProperty);
      }


      if (orderBy != null) return orderBy(query).ToList();
      else return query.ToList();
    }


Your Get method causes a query to execute (you are using ToList() at the end of the method). This leads to a big difference:

  • Your first query looks up all rows with id <= 5 in the database and materializes only those rows as entities. So you get max. 5 objects in memory (given that your smallest id is 1).

  • Your second query does not have a filter at all which is applied in SQL. So it sorts the whole table descending by id and then returns the full table and as many objects as there are rows in the table will get materialized in memory. On this in-memory collection you apply Take(5) (LINQ to Objects, not LINQ to Entities) which means that you then throw away all objects except the first five.

The second query is bad. Take(5) should be performed on your IQueryable inside of your Get method to make sure that the selection for the first 5 rows happens actually in the database and only those 5 objects get created in memory.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜