gpt4 book ai didi

c# - 异步方法不适用于 ObjectResult

转载 作者:太空狗 更新时间:2023-10-29 20:58:25 28 4
gpt4 key购买 nike

根据documentation对于 EF6,ObjectResult 实现 IDbAsyncEnumerable <T> , IDbAsyncEnumerable - 这应该意味着它实现了异步方法,例如 ObjectResult <T> .ToListAsync(),对吧?

但是,当像这样调用存储过程时,我不认为这是 Visual Studio 中可能的方法:

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

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

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

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

最佳答案

更新

由于您不能只转换为 Queryable,我已经反编译了 EF 用于 IDbAsyncEnumerable 的内部方法,并制作了这个扩展方法(来自 Microsoft 反编译源,所以它应该是尽善尽美):

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

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

并且您可以在没有 CancellationToken 的情况下进行重载,例如:

public static Task<List<T>> ToListAsync<T>(this IDbAsyncEnumerable<T> source)
{
return ToListAsync<T>(source, CancellationToken.None);
}

旧答案(无效)

不确定我是否捕获了问题的正确抓地力,但你不能简单地这样做吗?

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

关于c# - 异步方法不适用于 ObjectResult<T>,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34227749/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com