Entity Framework Core CompileAsyncQuery 语法来执行返回列表的查询?

问题描述 投票:0回答:1

有关编译异步查询的在线文档和示例有点稀疏,所以我不妨在这里寻求指导。

假设我有一个像这样的存储库模式方法来查询表中的所有条目:

public async Task<List<ProgramSchedule>> GetAllProgramsScheduledList()
{
    using (var context = new MyDataContext(_dbOptions))
    {
        context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
        return await context.ProgramsScheduledLists.ToListAsync();
    }
}

这个效果很好。

现在我想做同样的事情,但是使用异步编译查询

我设法编译它的一种方法是使用以下语法:

static readonly Func<MyDataContext, Task<List<ProgramSchedule>>> GetAllProgramsScheduledListQuery;

static ProgramsScheduledListRepository()
{
    GetAllProgramsScheduledListQuery = EF.CompileAsyncQuery<MyDataContext, List<ProgramSchedule>>(t => t.ProgramsScheduledLists.ToList());
}

public async Task<List<ProgramSchedule>> GetAllProgramsScheduledList()
{
    using (var context = new MyDataContext(_dbOptions))
    {
        context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
        return await GetAllProgramsScheduledListQuery(context);
    }
}

但是在运行时会抛出此异常:

System.ArgumentException: Expression of type 'System.Collections.Generic.List`1[Model.Scheduling.ProgramSchedule]' cannot be used for return type 'System.Threading.Tasks.Task`1[System.Collections.Generic.List`1[Model.Scheduling.ProgramSchedule]]'

奇怪的是,如果我使用任何其他运算符(例如 SingleOrDefault),它工作正常。只是返回列表有问题。

为什么?

async-await entity-framework-core
1个回答
6
投票

EF.CompileAsync
对于记录集,返回
IAsyncEnumrable<T>
。要从此类查询中获取
List
,您必须枚举
IAsyncEnumrable
并填写
List
,

private static Func<MyDataContext, IAsyncEnumerable<ProgramSchedule>> compiledQuery =
    EF.CompileAsyncQuery((MyDataContext ctx) =>
        ctx.ProgramsScheduledLists);

public static async Task<List<ProgramSchedule>> GetAllProgramsScheduledList(CancellationToken ct = default)
{
    using (var context = new MyDataContext(_dbOptions))
    {
        context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

        var result = new List<ProgramSchedule>();
        await foreach (var s in compiledQuery(context).WithCancellation(ct))
        {
            result.Add(s);
        }

        return result;
    }
}

Package System.Linq.Async 已针对此类情况预定义了扩展,

ToListAsync()
ToArrayAsync()
等。

© www.soinside.com 2019 - 2024. All rights reserved.