当前位置:  开发笔记 > 编程语言 > 正文

ObjectResult <T>不可用的异步方法

如何解决《ObjectResult<T>不可用的异步方法》经验,为你挑选了1个好方法。

根据EF6 的文档,ObjectResult实现了IDbAsyncEnumerable ,IDbAsyncEnumerable - 这应该意味着它实现了异步方法,如ObjectResult .ToListAsync(),对吗?

但是,在调用这样的存储过程时,我并没有将其视为Visual Studio中的可能方法:

public async Task> GetResultFromMyStoredProcedure(string foo, string bar)
{
    return await context.My_Stored_Procedure(foo, bar).ToListAsync();
}

但是将存储过程作为查询调用似乎确实有效:

public async Task> GetResultFromMyStoredProcedure(string foo, string bar)
{
    var fooParam = new SqlParameter("@foo", foo);
    var barParam = new SqlParameter("@bar", bar);
    return await context.Database.SqlQuery("My_Stored_Procedure @foo, @bar", fooParam, barParam).ToListAsync();
}

我确保我的项目引用了正确的EF dll(6.1.3) - 使用NuGet.我错过了什么?



1> Jcl..:
更新

既然你不能只转换为Queryable,我已经反编译了EF使用的内部方法IDbAsyncEnumerable并制作了这个扩展方法(在微软反编译源中,所以它应该尽可能好):

public static Task> ToListAsync(this IDbAsyncEnumerable source, CancellationToken cancellationToken)
{
    TaskCompletionSource> tcs = new TaskCompletionSource>();
    List list = new List();
    ForEachAsync(source.GetAsyncEnumerator(), new Action(list.Add), cancellationToken).ContinueWith((Action)(t =>
    {
        if (t.IsFaulted)
            tcs.TrySetException((IEnumerable)t.Exception.InnerExceptions);
        else if (t.IsCanceled)
            tcs.TrySetCanceled();
        else
            tcs.TrySetResult(list);
    }), TaskContinuationOptions.ExecuteSynchronously);
    return tcs.Task;
}

private static async Task ForEachAsync(IDbAsyncEnumerator enumerator, Action action, CancellationToken cancellationToken)
{
    using (enumerator)
    {
        cancellationToken.ThrowIfCancellationRequested();
        if (await System.Data.Entity.Utilities.TaskExtensions.WithCurrentCulture(enumerator.MoveNextAsync(cancellationToken)))
        {
            Task moveNextTask;
            do
            {
                cancellationToken.ThrowIfCancellationRequested();
                T current = enumerator.Current;
                moveNextTask = enumerator.MoveNextAsync(cancellationToken);
                action(current);
            }
            while (await System.Data.Entity.Utilities.TaskExtensions.WithCurrentCulture(moveNextTask));
        }
    }
}

而你可以有一个过载而不CancellationToken喜欢:

public static Task> ToListAsync(this IDbAsyncEnumerable source)
{
   return ToListAsync(source, CancellationToken.None);
}
旧答案(不工作)

不确定我是否能抓住问题,但你不能简单地做到这一点吗?

return await context.My_Stored_Procedure(foo, bar).AsQueryable().ToListAsync();

推荐阅读
jerry613
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有