我正在将使用 Entity Framework 和 SQL Server 数据库的现有应用程序从 .NET Framework 移植到 .NET Core。在 EF6 中,您可以执行以下操作:
private async Task<IEnumerable<T>> GetByExpressionAsync(Expression<Func<T, bool>> where))
{
return await _context.DbSet<T>().Where(where).ToListAsync();
}
假设where
表达式可以在服务器端进行评估,这将转换为 SQL 查询,如SELECT columns FROM table WHERE Foo=1
.
这与 EF Core 中的方法相同。是的,我意识到我没有利用异步流,但请记住这是一个现有的应用程序,我没有时间真正重新设计它。
private async Task<IEnumerable<T>> GetByExpressionAsync(Expression<Func<T, bool>> where))
{
return await _context.DbSet<T>().AsAsyncEnumerable().Where(where.Compile()).ToListAsync();
}
我遇到问题的表有数十万条记录。如果我使用 SQL Profiler,我可以看到没有WHERE
子句,因此 SQL Server 正在返回整个表,这当然不是很理想。一开始我没有注意到,因为我的单元测试是针对一个小得多的表运行的,所以没有迹象表明会有性能问题。
根据Microsoft 文档,“数据库提供程序确定可以在数据库中评估查询的哪些部分”和“查询的这些部分被翻译为特定于数据库的查询语言”。因此,当我使用简单的[column] == [value]
过滤器时,它应该可以正常工作,并且确实,同步工作完全符合预期。
private IEnumerable<T> GetByExpression(Expression<Func<T, bool>> where))
{
return _context.DbSet<T>().AsQueryable().Where(where).ToList();
}
我究竟做错了什么?提前致谢。