如何在不枚举数据的情况下进行异步查询?

时间:2019-04-14 21:07:02

标签: c# asynchronous entity-framework-core

我正在尝试弄清楚如何在不枚举数据的情况下在Entity Framework Core中编写通用的异步Olaf,Annie,3 Galio,Annie,5 Twisted Fate,Annie,6 Xin Zhao,Annie,1 Urgot,Annie,10 LeBlanc,Annie,9 Vladimir,Annie,11 Kayle,Twisted Fate,12 LeBlanc,Xin Zhao,2 Galio,Galio,6 数据库方法。我希望GetAll<T>是异步的,但是不希望它枚举数据,因此我可以在以后添加一个GetAll<T>方法,并将其应用于数据库查询。

Where

MSDN's article on async queries显示以下内容...

List<Customer> customers = await _customerRepository.GetAll()
  .Where(c => c.Name.StartsWith("a"))
  .ToList();

...但是,(如果我理解正确的话)对public async Task<List<Blog>> GetBlogsAsync() { using (var context = new BloggingContext()) { return await context.Blogs.ToListAsync(); } } 的调用将枚举数据,这意味着它将把整个ToListAsync()数据集加载到内存中,然后才应用将对结果应用Blogs方法。

我可以使用一个异步方法来返回Where吗?

如果这样做是更好的方法,我很高兴不使用存储库。 This article暗示EF Core不能从存储库中受益,但我也看不到如何按照自己的方式做。

更新:为了澄清(感谢DavidG),这个想法是我的ASP.NET Core控制器可以注入一个存储库,并且可以执行异步查询来获取数据。我正在考虑使存储库具有通用性,并在控制器中进行过滤,因此出现了问题。我知道我可以编写一个IEnumerable<T>并拥有一个CustomersRepository方法,但是存储库变得肿了。我一直在寻找像posisble这样简单的存储库。

1 个答案:

答案 0 :(得分:3)

最安全的做法是允许调用者(在您的情况下为控制器,尽管我建议您将逻辑保留在它们之外)传递自己的过滤器。例如:

public async Task<List<T>> GetAsync<T>(params Expression<Func<T, bool>>[] filters)
{
    IQueryable<T> query = _context.Set<T>();    

    if(filters != null)
    {
        foreach (var filter in filters)
        {
            query = query.Where(filter);
        }
    }

    return await query.ToListAsync();
}

并这样称呼它:

var allUsers = await repository.GetAsync<User>();

var zombies = await repository.GetAsync<User>(u => u.IsUndead == true);

var zombieDevelopers = await repository.GetAsync<User>(
    u => u.IsUndead = true,
    u => u.JobTitle = "Developer");