I'm porting an existing application that uses Entity Framework with a SQL Server database from .NET Framework to .NET Core. In EF6, you could do:
private async Task<IEnumerable<T>> GetByExpressionAsync(Expression<Func<T, bool>> where))
{
return await _context.DbSet<T>().Where(where).ToListAsync();
}
Assuming that the where
expression could be evaluated server-side, this would translate to a SQL query like SELECT columns FROM table WHERE Foo=1
.
This is the same method in EF Core. Yes, I realize I'm not taking advantage of async streams, but remember this is an existing application and I don't have the time to really redesign it.
private async Task<IEnumerable<T>> GetByExpressionAsync(Expression<Func<T, bool>> where))
{
return await _context.DbSet<T>().AsAsyncEnumerable().Where(where.Compile()).ToListAsync();
}
The table that I'm having the problem with has hundreds of thousands of records. If I use SQL Profiler, I can see that there is no WHERE
clause, so SQL Server is returning the entire table, which is of course so not ideal. I didn't notice at first because my unit tests run against a much smaller table so there was no indication there would be a performance issue.
According to the Microsoft documentation, "The database provider identifies which parts of the query can be evaluated in the database" and "These parts of the query are translated to database-specific query language". So when I use simple [column] == [value]
filters, this should work properly, and indeed, the synchronous works exactly as expected.
private IEnumerable<T> GetByExpression(Expression<Func<T, bool>> where))
{
return _context.DbSet<T>().AsQueryable().Where(where).ToList();
}
What am I doing wrong? Thanks in advance.