You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 04:22:36