简体   繁体   中英

LINQ query performance when applying Where clause

I have a question about Entity Framework.

I would be grateful if someone can kindly explain some details of how the chain calls work between LINQ and Entity Framework (and at what point the query is executed on the DB side).

I'd like to know the performance differences (if any) of writing out a LINQ query in two versions of the methods below:

Method 1:

public IEnumerable<T> GetList(Expression<Func<T, bool>> expression, params     Expression<Func<T, object>>[] includeProperties)
{
    var results = dbSet.Where(expression).AsQueryable().AsNoTracking();
    return includeProperties.Aggregate(results, (current, include) => current.Include(include));
}

Function call like this:

GetList(x => x.ID == id);

Method 2:

public IEnumerable<T> GetList(params Expression<Func<T, object>>[] includeProperties)
{
    var results = dbSet.AsQueryable().AsNoTracking();
    return includeProperties.Aggregate(results, (current, include) => current.Include(include));
}

Function call like this:

GetList().Where(x => x.ID == id);

The difference is that your routines are returning an IEnumerable<T> instead of an IQueryable<T> . In your second case, the Where will use the IEnumerable's version instead of IQueryable's. The "chaining" sort of stops there (The server-side chain stops, and a client-side chain begins). No more changes after that point will have any effect on the SQL that is generated. Once you try and enumerate the results, it will cause all the records to be returned from the datasource and then be filtered on the client side where the first will filter on the datasource side because you did the Where while it was still an IQueryable.

Change your routines to return an IQueryable<T> instead, and then they should be identical in terms of execution and performance.

** Side note, in Method 1, the .AsQueryable() is redundant. It's already an IQueryable.

This is how I would expect such a function to be written:

public IQueryable<T> GetList(params Expression<Func<T, object>>[] includeProperties)
{
  var results = dbSet.AsNoTracking().AsQueryable();
  return includeProperties.Aggregate(results, (current, include) => current.Include(include));
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM