2015-12-11 41 views
3

按照documentation爲EF6異步方法,ObjectResult實現IDbAsyncEnumerable <T>,IDbAsyncEnumerable - 這應該意味着它實現如ObjectResult <T>異步方法。 ToListAsync(),對吧?不適用於ObjectResult <T>

不過,我沒有看到,調用在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。我錯過了什麼?

+0

那麼你會得到什麼確切的錯誤信息? –

+0

ObjectResult 不包含「ToListAsync」的定義。 – DarkSkyForever

+0

那麼你期望它使用哪個確切的'ToListAsync'方法?它不是'IDbAsyncEnumerable '的一部分,所以大概你期待一個擴展方法......你有那種方法的文檔嗎? –

回答

8

更新

既然你不能只是轉換爲可查詢的,我反編譯的是EF用來IDbAsyncEnumerable內部方法和製造這種擴展方法(從微軟反編譯源,所以它應該是一樣好因爲它得到):

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); 
} 

老ANS wer(無法正常工作

不確定我是否掌握了這個問題的正確答案,但難道你不能簡單地這樣做嗎?

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

不幸的是;這是我嘗試過的第一件事情之一。它編譯得很好,但有一個運行時錯誤。 – DarkSkyForever

+0

我看,讓我編輯 – Jcl

+0

忘了顯示異常:消息=「源IQueryable沒有實現IDbAsyncEnumerable 。只有實現IDbAsyncEnumerable的源可以用於實體框架異步操作 – DarkSkyForever

相關問題