Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 异步LINQ_C#_.net_Entity Framework_Linq - Fatal编程技术网

C# 异步LINQ

C# 异步LINQ,c#,.net,entity-framework,linq,C#,.net,Entity Framework,Linq,我正在寻找一个异步.Where(),但找不到,所以经过一些研究,我创建了一个 public static class LinqExtension { public static async Task<IEnumerable<T>> WhereAsync<T>(this IEnumerable<T> source, Func<T, Task<bool>> @delegate) { var tas

我正在寻找一个异步
.Where()
,但找不到,所以经过一些研究,我创建了一个

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;
    }
}
我试过了

var q = await context.StockHistories.WhereAsync(x => x.ProductId == productId);
context.StockHistories.WhereAsync(Task.Run(() => { x => x.ProductId == productId; }));
但是

只有赋值、调用、递增、递减和新对象 表达式可以用作语句


有人能提供一个解决方案并解释我做错了什么吗?

EF的异步方法就是执行查询的方法。所以你真正想要的是

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

基本上没有一个异步
Where
方法,因为它只是用来生成将在数据库上执行的实际SQL,所以没有意义。直到您迭代结果,查询才真正运行,所有执行查询的方法都有一个异步版本。

EF的异步方法是执行查询的方法。所以你真正想要的是

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

基本上没有一个异步
Where
方法,因为它只是用来生成将在数据库上执行的实际SQL,所以没有意义。在迭代结果之前,查询实际上不会运行,所有执行该操作的方法都有一个异步版本。

使lambda表达式异步不会使方法异步,因为它只是将其转换为SQL。异步方法就是那些将运行查询的方法,如
ToListAsync
FirstOrDefaultAsync
。这看起来像是来自被动扩展而不是LINQ。@Ephoric您如何将被动扩展与EF一起使用?@juharr这不是使用EF。如果他正在创建自己的Where方法,EF将把所有数据加载到内存中,然后在CPU上运行Where。它不会成为SQL查询的一部分。而且,他使用的是IEnumerable,而不是IQueryable。实体框架标记是错误的。使lambda表达式异步不会使方法异步,因为它只是将其转换为SQL。异步方法就是那些将运行查询的方法,如
ToListAsync
FirstOrDefaultAsync
。这看起来像是来自被动扩展而不是LINQ。@Ephoric您如何将被动扩展与EF一起使用?@juharr这不是使用EF。如果他正在创建自己的Where方法,EF将把所有数据加载到内存中,然后在CPU上运行Where。它不会成为SQL查询的一部分。而且,他使用的是IEnumerable,而不是IQueryable。实体框架标签是错误的。我认为OP没有一个
Func
,它可以接受
StockHistory
并同步生成
bool
。他们可以在
Where
委托中使用
Result
进行阻止,但这不是很好的性能。刚刚注意到这是EF;因此,委托从未被实际计算过。@AsadSaeeduddin是的,lambda传递到
中,其中
被转换为SQL。我认为OP没有一个
Func
,它可以接受
StockHistory
并同步生成
bool
。他们可以在
Where
委托中使用
Result
进行阻止,但这不是很好的性能。刚刚注意到这是EF;因此,委托从未被实际计算过。@AsadSaeeduddin是的,lambda被传递到
,其中
被转换为SQL。