应用 Where 子句时的 LINQ 查询性能
LINQ query performance when applying Where clause
我有一个关于 Entity Framework 的问题。
如果有人能解释一下 LINQ 和 Entity Framework 之间的链调用如何工作的一些细节(以及在什么时候在数据库端执行查询),我将不胜感激。
我想知道在以下两个版本的方法中编写 LINQ 查询的性能差异(如果有的话):
方法一:
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));
}
像这样的函数调用:
GetList(x => x.ID == id);
方法二:
public IEnumerable<T> GetList(params Expression<Func<T, object>>[] includeProperties)
{
var results = dbSet.AsQueryable().AsNoTracking();
return includeProperties.Aggregate(results, (current, include) => current.Include(include));
}
像这样的函数调用:
GetList().Where(x => x.ID == id);
不同之处在于您的例程是 returning IEnumerable<T>
而不是 IQueryable<T>
。在第二种情况下,Where 将使用 IEnumerable 的版本而不是 IQueryable 的版本。 "chaining" 在那里停止(服务器端链停止,客户端链开始)。之后的任何更改都不会对生成的 SQL 产生任何影响。一旦您尝试枚举结果,它将导致所有记录都从数据源中 returned,然后在客户端进行过滤,其中第一个将在数据源端进行过滤,因为您在 Where 进行了操作仍然是 IQueryable。
将您的例程更改为 return 和 IQueryable<T>
,然后它们在执行和性能方面应该是相同的。
** 旁注,在方法 1 中,.AsQueryable() 是多余的。它已经是一个 IQueryable。
我希望这样的函数是这样写的:
public IQueryable<T> GetList(params Expression<Func<T, object>>[] includeProperties)
{
var results = dbSet.AsNoTracking().AsQueryable();
return includeProperties.Aggregate(results, (current, include) => current.Include(include));
}
我有一个关于 Entity Framework 的问题。
如果有人能解释一下 LINQ 和 Entity Framework 之间的链调用如何工作的一些细节(以及在什么时候在数据库端执行查询),我将不胜感激。
我想知道在以下两个版本的方法中编写 LINQ 查询的性能差异(如果有的话):
方法一:
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));
}
像这样的函数调用:
GetList(x => x.ID == id);
方法二:
public IEnumerable<T> GetList(params Expression<Func<T, object>>[] includeProperties)
{
var results = dbSet.AsQueryable().AsNoTracking();
return includeProperties.Aggregate(results, (current, include) => current.Include(include));
}
像这样的函数调用:
GetList().Where(x => x.ID == id);
不同之处在于您的例程是 returning IEnumerable<T>
而不是 IQueryable<T>
。在第二种情况下,Where 将使用 IEnumerable 的版本而不是 IQueryable 的版本。 "chaining" 在那里停止(服务器端链停止,客户端链开始)。之后的任何更改都不会对生成的 SQL 产生任何影响。一旦您尝试枚举结果,它将导致所有记录都从数据源中 returned,然后在客户端进行过滤,其中第一个将在数据源端进行过滤,因为您在 Where 进行了操作仍然是 IQueryable。
将您的例程更改为 return 和 IQueryable<T>
,然后它们在执行和性能方面应该是相同的。
** 旁注,在方法 1 中,.AsQueryable() 是多余的。它已经是一个 IQueryable。
我希望这样的函数是这样写的:
public IQueryable<T> GetList(params Expression<Func<T, object>>[] includeProperties)
{
var results = dbSet.AsNoTracking().AsQueryable();
return includeProperties.Aggregate(results, (current, include) => current.Include(include));
}