【问题标题】:How to chain async calls in a complex linq query如何在复杂的 linq 查询中链接异步调用
【发布时间】:2021-03-24 03:50:46
【问题描述】:

在 .NET 应用程序中,我试图在 repo 层上构造一个 DTO,如下所示。但是,我在语句的深处有一个讨厌的异步函数。我应该如何链接异步调用?

var subtopics; // I have a subtopics array

var topicModel = new TopicModel
{
    Id = 0,
    SubtopicModels = subtopics
        .Select(subtopic => new SubtopicModel
        {
            Id = 0,
            VideoModels = subtopic.Videos // simple await on this line doesn't work
                .OrderBy(video => video.OrderInSubtopic)
                .Select(async video => new VideoModel
                {
                    Id = 0,
                    VideoLeftAtSeconds = (await _db.VideoActivities
                        .FirstOrDefaultAsync(activity => activity.UserId == userId && activity.VideoId == videoId))
                        .LeftAtSeconds
                }).ToList()
        }).ToList(),
};

【问题讨论】:

  • 这就是整体框架核心吗?子主题从何而来?
  • @DanielA.White 子主题来自哪里并不重要。我排除了所有不相关的代码。我在此代码部分之前有一个子主题数组
  • 对不起,你的所作所为很糟糕。如果 suptopic.Videos 集合中有 20 个项目,您将创建 20 个对数据库的查询,这将影响性能。
  • @daney89 那我该怎么办?我想知道你的想法。

标签: c# linq async-await entity-framework-core


【解决方案1】:

问题在于,给予最深 Select (.Select(async video => ...) 的 lambda 将返回 Task<T>(我假设 Task<int> 但从上下文中不确定)。

Select 不了解如何使用Task,只会按原样传递。您可以使用WhenAll (1) 批量转换它们,但您必须对数据库连接进行额外的设置,因为这将并行执行多个查询。 (2)

在这种情况下,最简单的方法可能是废弃 LINQ 并使用foreach,如下所示:

var subtopics;

var topicModel = new TopicModel
{
    Id = 0,
    SubtopicModels = new List<SubtopicModel>()
};

foreach(var subtopic in subtopics)
{
    var subtopicModel = new SubtopicModel
    {
        Id = 0,
        VideoModels = new List<VideoModel>()
    };

    foreach(var video in subtopic.Videos.OrderBy(video => video.OrderInSubtopic))
    {
        subtopicModel.VideoModels.Add(new VideoModel
        {
            Id = 0,
            VideoLeftAtSeconds = (await _db.VideoActivities
                        .FirstOrDefaultAsync(activity => activity.UserId == userId && activity.VideoId == videoId))
                        .LeftAtSeconds
        });
    }

    topicModel.SubtopicModel.Add(subtopicModel);
}

【讨论】:

    猜你喜欢
    • 2022-01-17
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多