根据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.我错过了什么?
既然你不能只转换为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();