我试图弄清楚如何在不枚举数据的情况下在Entity Framework Core中编写通用的异步GetAll<T>
数据库方法。我希望GetAll<T>
是异步的,但不希望它枚举数据,以便以后可以添加Where
方法并将其应用于数据库查询。
List<Customer> customers = await _customerRepository.GetAll()
.Where(c => c.Name.StartsWith("a"))
.ToList();
MSDN's article on async queries显示以下内容...
public async Task<List<Blog>> GetBlogsAsync()
{
using (var context = new BloggingContext())
{
return await context.Blogs.ToListAsync();
}
}
...但是(如果我理解正确的话)对
ToListAsync()
的调用将枚举数据,这意味着它将把整个Blogs
数据集加载到内存中,并且仅在此之后应用Where
方法应用于的任何过滤结果将指定。我可以使用一个异步方法来代替
IEnumerable<T>
吗?如果这样做是更好的方法,我很高兴不使用存储库。 This article表示EF Core不能从存储库中受益,但是我也看不到如何按照自己的方式去做。
更新:为了澄清(感谢DavidG),这个想法是我的ASP.NET Core控制器可以具有注入的存储库,并且可以执行异步查询来获取数据。我正在考虑使存储库具有通用性,并在控制器中进行过滤,因此出现了问题。我知道我可以编写一个
CustomersRepository
并具有一个CustomersThatStartWith
方法,但是随后存储库变得肿。我一直在寻找像posisble这样简单的存储库。 最佳答案
最安全的做法是允许调用者(在您的情况下为控制器,尽管我建议您将逻辑保留在它们之外)传递自己的过滤器。例如:
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");
关于c# - 如何在不枚举数据的情况下进行异步查询?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/55680032/