2016-07-19 4 views
0

Я искал async .Where(), но не смог найти его, после некоторых исследований, которые я создал.Asynchronous LINQ

public static class LinqExtension 
{ 
    public static async Task<IEnumerable<T>> WhereAsync<T>(this IEnumerable<T> source, Func<T, Task<bool>> @delegate) 
    { 
     var tasks = source.Select(async t => new 
     { 
      Predicate = await @delegate(t).ConfigureAwait(false), 
      Value = t 
     }).ToList(); 

     var results = await Task.WhenAll(tasks).ConfigureAwait(false); 

     IEnumerable<T> typeList = results.Where(pred => pred.Predicate).Select(val => val.Value); 
     return typeList; 
    } 
} 

Когда я пытаюсь использовать его я получаю сообщение об ошибке выполнения

Не удается преобразовать неявным типа BOOL к задаче и да, это правильно

Это, как я пытался

var q = await context.StockHistories.WhereAsync(x => x.ProductId == productId); 

Я пробовал

context.StockHistories.WhereAsync(Task.Run(() => { x => x.ProductId == productId; })); 

но получить

Только назначение, вызов, увеличение, уменьшение, и новые выражения объекта могут быть использованы в качестве заявления

Может угодить кто-то обеспечить решение и объяснить, что я делать не так?

+1

Создание асинхронного выражения лямбда не будет делать метод async, потому что он просто переводит это в SQL. Асинхронные методы - это только те, которые будут запускать запрос типа «ToListAsync» или «FirstOrDefaultAsync». – juharr

+0

Это похоже на что-то из Reactive Extensions, а не LINQ. – Euphoric

+0

@Euphoric Как бы вы использовали Reactive Extensions с EF? – juharr

ответ

5

Асинхронные методы для EF - это те, которые выполняют запрос. Так что вы на самом деле хотите,

var q = await context.StockHistories.Where(x => x.ProductId == productId).ToListAsync(); 

В принципе не существует асинхронный Where метод, потому что это не имеет смысла, чтобы иметь один, потому что он используется только для создания фактического SQL, который будет выполняться на БД. Запрос фактически не выполняется до тех пор, пока вы не выполните итерацию результатов, а все методы, которые имеют асинхронную версию.

+0

Я думаю, что OP не имеет 'Func', который может принимать' StockHistory' и производить 'bool' синхронно. Они могут блокировать использование 'Result' в делегате' Where', но это не очень хорошо. –

+0

Ah, nvm. Просто заметил, что это EF; поэтому делегат никогда не оценивается. –

+0

@AsadSaeeduddin Да, лямбда передана в 'Where', переведена на SQL. – juharr