英文:
EF Core async LINQ Where(predicate).ToListAsync() Error: CS1061 IEnumerable does not contain ToListAsync()
问题
I have a context class EFCoreMContext
with a defined property EFCore.DBSet<AccessTime> AccessTime
. Then there's a repository class CAccessTimeRepository
with async functions. The issue arises when trying to use ToListAsync()
, and Visual Studio highlights it with an error. The problem is that when using .Where()
with a specific predicate, it returns an IEnumerable
, while .Where(x => x.ID == 1)
returns an IQueryable
. To address this, you attempted to use .AsQueryable()
, but it resulted in an error.
The error occurs because the source 'IQueryable' doesn't implement 'IAsyncEnumerable<_3TierApp.DAL.Entities.AccessTime>'. Only sources that implement 'IAsyncEnumerable' can be used for Entity Framework asynchronous operations.
The reason for the different return types of .Where()
is likely due to how Entity Framework processes the query based on the provided predicate. To resolve this issue, you can use ToListAsync()
directly without .AsQueryable()
:
public async Task<IEnumerable<AccessTime>> FindAsync(Func<AccessTime, bool> predicate)
{
return await db.AccessTime
.Where(predicate)
.ToListAsync();
}
This should work as expected and return the desired IEnumerable<AccessTime>
.
英文:
So I have a context class EFCoreMContext
with defined property EFCore.DBSet<AccessTime> AccessTime
public class EFCoreMContext : Microsoft.EntityFrameworkCore.DbContext
{
public Microsoft.EntityFrameworkCore.DbSet<User> Users { get; set; }
public Microsoft.EntityFrameworkCore.DbSet<AccessTime> AccessTime { get; set; }
...
}
Then I have a repository class CAccessTimeRepository
public class CAccessTimeRepository : IRepository<AccessTime>
{
private EFCoreMContext db;
public CAccessTimeRepository(EFCoreMContext context)
{
this.db = context;
}
...
with async functions:
public async Task<IEnumerable<AccessTime>> FindAsync(Func<AccessTime, bool> predicate)
{
return await db.AccessTime.Where(predicate).ToListAsync();
}
...
}
The trouble is when I try to use this ToListAsync()
- Visual Studio highlights it with an error
> CS1061 IEnumerable does not contain ToListAsync()
The thing is when I use .Where()
with something like this
.Where(x => x.ID == 1)
it returns an IQueryable
, so I can use ToListAsync()
. But when I use this method with my predicate, it returns IEnumerable
.
So deal with it I try to pass this code with an AsQueryable
public async Task<IEnumerable<AccessTime>> FindAsync(Func<AccessTime, bool> predicate)
{
return await db.AccessTime
.Where(predicate)
.AsQueryable()
.ToListAsync();
}
While executing this code I get an error:
> The source 'IQueryable' doesn't implement 'IAsyncEnumerable<_3TierApp.DAL.Entities.AccessTime>'. Only sources that implement 'IAsyncEnumerable' can be used for Entity Framework asynchronous operations.
I have no idea why .Where()
with my predicate and with x => x.Id
returns different types.
Can somebody explain? And also what will be the best working solution for this?
答案1
得分: 3
EF Core的扩展,如EntityFrameworkQueryableExtensions.ToListAsync
,与IQueryable
接口一起使用(请查看链接的方法签名),而不是IEnumerable
,而IQueryable
需要Expression<Func<...>>
(例如Queryable.Where
)而不仅仅是Func<...>
(允许分析传递的表达式树并生成SQL查询),因此请相应地更改签名:
public async Task<IEnumerable<AccessTime>> FindAsync(
Expression<Func<AccessTime, bool>> predicate)
{
return await db.AccessTime
.Where(predicate)
.ToListAsync();
}
阅读更多:
英文:
EF Core's extensions like EntityFrameworkQueryableExtensions.ToListAsync
work with IQueryable
interface (check out the linked method signature), not an IEnumerable
and IQueryable
requires Expression<Func<...>>
(Queryable.Where
for example) not just Func<...>
(which allows to analyze passed expression tree and generate SQL query), so change the signature accordingly:
public async Task<IEnumerable<AccessTime>> FindAsync(
Expression<Func<AccessTime, bool>> predicate)
{
return await db.AccessTime
.Where(predicate)
.ToListAsync();
}
Read more:
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论