如何在LINQ中使用AsAsyncEnumerable替代AsEnumerable?
问题描述
我有如下方法:
public async Task<List<string>> FindUsedComments(List<string> commentIds) { if (!commentIds.Any()) return new List<string>(); var usedCommentIds = GetNoTraking.Select(x => x.OrginalCommentId).AsEnumerable().Intersect(commentIds).ToList(); return usedCommentIds; }
该方法运行正常,但将其中的AsEnumerable改为AsAsyncEnumerable后出现报错:
'IAsyncEnumerable
' does not contain a definition for 'Intersect' and the best extension method overload 'ParallelEnumerable.Intersect (ParallelQuery , IEnumerable )' requires a receiver of type 'System.Linq.ParallelQuery '
请问如何在该方法中用AsAsyncEnumerable替代AsEnumerable?
解决方案
方案1:使用System.Linq.Async NuGet包
这是最直接的解决方式,该NuGet包提供了IAsyncEnumerable<T>的全套异步LINQ扩展方法,其中就包含IntersectAsync。
安装包后,修改代码如下:
using System.Linq; public async Task<List<string>> FindUsedComments(List<string> commentIds) { if (!commentIds.Any()) return new List<string>(); var usedCommentIds = await GetNoTraking.Select(x => x.OrginalCommentId) .AsAsyncEnumerable() .IntersectAsync(commentIds) .ToListAsync(); return usedCommentIds; }
方案2:先将异步序列转为列表(无需额外NuGet包)
如果不想引入新的依赖,可以先通过ToListAsync()把异步枚举的结果加载到内存,再使用普通的Intersect方法:
public async Task<List<string>> FindUsedComments(List<string> commentIds) { if (!commentIds.Any()) return new List<string>(); var dbCommentIds = await GetNoTraking.Select(x => x.OrginalCommentId) .AsAsyncEnumerable() .ToListAsync(); var usedCommentIds = dbCommentIds.Intersect(commentIds).ToList(); return usedCommentIds; }
方案3:手动异步筛选(性能优化版)
如果数据量较大,用HashSet存储目标ID能提升筛选效率,避免两次全量遍历:
public async Task<List<string>> FindUsedComments(List<string> commentIds) { if (!commentIds.Any()) return new List<string>(); var commentIdSet = new HashSet<string>(commentIds); var usedCommentIds = new List<string>(); await foreach (var id in GetNoTraking.Select(x => x.OrginalCommentId).AsAsyncEnumerable()) { if (commentIdSet.Contains(id)) { usedCommentIds.Add(id); // 可选优化:移除已匹配的ID,避免重复添加,提前终止遍历 commentIdSet.Remove(id); if (commentIdSet.Count == 0) break; } } return usedCommentIds; }
内容的提问来源于stack exchange,提问作者ArshamCoder
相关产品推荐
相关产品推荐

