【发布时间】:2021-06-02 12:42:01
【问题描述】:
我目前正在编写这样的方法:
public async Task<UserModel> GetUserByUserIdAsync(string userId)
{
IQueryable<UserEntity> usersQuery = BuildQueryable(userId);
bool any = await usersQuery.ExecuteQuery().AnyAsync();
if (!any) return null; // wanna do other logic in the future
return (await usersQuery.ExecuteQuery().SingleAsync()).ToUserModel();
}
如您所见,我调用了两次await usersQuery.ExecuteQuery(),ExecuteQuery() 是一种迭代我的数据库的方法,可能被认为是一项昂贵的操作。有什么方法可以保存我的IAsyncEnumerable<T>,就像我通常使用IEnumerable<T> 一样,并在我的代码中重复使用它?
我考虑过在上面使用ToListAsync(),但我不确定这是否被认为是好的做法。我还读到我可以返回一个Task<IAsyncEnumerable<T>> 并用它做点什么。处理这个问题的最佳方法是什么?我想实施最有效的解决方案。
【问题讨论】:
-
自己编写 foreach 怎么样,这样您就可以迭代一次并自己处理所有突发事件?
-
"就像我通常使用 IEnumerable
并在我的代码中重复使用它一样?"你知道这同样适用于 IEnumerable<T>吗?再次迭代相同的IEnumerable<T>将当然也会再次获取底层数据存储。你必须以某种方式实现结果,我会选择ToListAsync。 -
@HimBromBeere 嗯,是的,但我相信不是在这种情况下。如果我的
ExecuteQuery()返回Task<List<T>>,我可以将列表保存在我的其他方法中,例如var dbResponse = ExecuteQuery();,然后我可以在整个方法中使用 dbResponse,而无需多次访问数据库。 -
@LasseV.Karlsen 你自己写foreach是什么意思?您是指
ExecuteQuery()方法中的foreach 吗?如果是这样,则应该读取给定查询的所有元素。你的意思是我应该用那种方法处理这些情况? -
在任何情况下,您至少会访问 DB 一次,因此只需执行
(await usersQuery.ExecuteQuery().FirstOrDefaultAsync()).ToUserModel()并将其与null进行比较以了解特定逻辑
标签: c# asynchronous task-parallel-library ienumerable iasyncenumerable