Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/340.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# 如何将可枚举转换为异步可枚举?_C#_.net_Linq_Entity Framework Core - Fatal编程技术网

C# 如何将可枚举转换为异步可枚举?

C# 如何将可枚举转换为异步可枚举?,c#,.net,linq,entity-framework-core,C#,.net,Linq,Entity Framework Core,我有一些代码使用Entity Framework Core中可用的异步扩展方法: public async Task<MyResult> DoQuery<T>(IQueryable<T> queryable) { var count = await queryable.CountAsync(); var firstItems = await queryable .Take(5) .ToArrayAsync();

我有一些代码使用Entity Framework Core中可用的异步扩展方法:

public async Task<MyResult> DoQuery<T>(IQueryable<T> queryable)
{
    var count = await queryable.CountAsync();
    var firstItems = await queryable
        .Take(5)
        .ToArrayAsync();

    return new MyResult(count, firstItems);
}
这失败了(这并不奇怪):

System.InvalidOperationException:源IQueryable的提供程序未实现IAsyncQueryProvider。只有实现IEntityQueryProvider的提供程序才能用于实体框架异步操作


看起来重构已经准备好了,但我很好奇:有没有办法将一个普通的可枚举文件转换成一个同步处理
CountAsync
的“虚拟”
AsyncEnumerable
AsyncQueryable
异步查询文件?

您需要创建一个内存中的
DbAsyncQueryProvider
来处理异步查询。关于如何做到这一点,有详细的解释。滚动至关于使用异步查询进行测试的部分。下面是从该链接复制粘贴的代码:

using System.Collections.Generic; 
using System.Data.Entity.Infrastructure; 
using System.Linq; 
using System.Linq.Expressions; 
using System.Threading; 
using System.Threading.Tasks; 

namespace TestingDemo 
{ 
    internal class TestDbAsyncQueryProvider<TEntity> : IDbAsyncQueryProvider 
    { 
        private readonly IQueryProvider _inner; 

        internal TestDbAsyncQueryProvider(IQueryProvider inner) 
        { 
            _inner = inner; 
        } 

        public IQueryable CreateQuery(Expression expression) 
        { 
            return new TestDbAsyncEnumerable<TEntity>(expression); 
        } 

        public IQueryable<TElement> CreateQuery<TElement>(Expression expression) 
        { 
            return new TestDbAsyncEnumerable<TElement>(expression); 
        } 

        public object Execute(Expression expression) 
        { 
            return _inner.Execute(expression); 
        } 

        public TResult Execute<TResult>(Expression expression) 
        { 
            return _inner.Execute<TResult>(expression); 
        } 

        public Task<object> ExecuteAsync(Expression expression, CancellationToken cancellationToken) 
        { 
            return Task.FromResult(Execute(expression)); 
        } 

        public Task<TResult> ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken) 
        { 
            return Task.FromResult(Execute<TResult>(expression)); 
        } 
    } 

    internal class TestDbAsyncEnumerable<T> : EnumerableQuery<T>, IDbAsyncEnumerable<T>, IQueryable<T> 
    { 
        public TestDbAsyncEnumerable(IEnumerable<T> enumerable) 
            : base(enumerable) 
        { } 

        public TestDbAsyncEnumerable(Expression expression) 
            : base(expression) 
        { } 

        public IDbAsyncEnumerator<T> GetAsyncEnumerator() 
        { 
            return new TestDbAsyncEnumerator<T>(this.AsEnumerable().GetEnumerator()); 
        } 

        IDbAsyncEnumerator IDbAsyncEnumerable.GetAsyncEnumerator() 
        { 
            return GetAsyncEnumerator(); 
        } 

        IQueryProvider IQueryable.Provider 
        { 
            get { return new TestDbAsyncQueryProvider<T>(this); } 
        } 
    } 

    internal class TestDbAsyncEnumerator<T> : IDbAsyncEnumerator<T> 
    { 
        private readonly IEnumerator<T> _inner; 

        public TestDbAsyncEnumerator(IEnumerator<T> inner) 
        { 
            _inner = inner; 
        } 

        public void Dispose() 
        { 
            _inner.Dispose(); 
        } 

        public Task<bool> MoveNextAsync(CancellationToken cancellationToken) 
        { 
            return Task.FromResult(_inner.MoveNext()); 
        } 

        public T Current 
        { 
            get { return _inner.Current; } 
        } 

        object IDbAsyncEnumerator.Current 
        { 
            get { return Current; } 
        } 
    } 
}
使用System.Collections.Generic;
使用System.Data.Entity.Infrastructure;
使用System.Linq;
使用System.Linq.Expressions;
使用系统线程;
使用System.Threading.Tasks;
命名空间测试演示
{ 
内部类TestDbAsyncQueryProvider:IDbAsyncQueryProvider
{ 
私有只读IQueryProvider\u内部;
内部测试DbaSyncQueryProvider(IQueryProvider内部)
{ 
_内部=内部;
} 
公共IQueryable CreateQuery(表达式)
{ 
返回新的TestDbAsyncEnumerable(表达式);
} 
公共IQueryable CreateQuery(表达式)
{ 
返回新的TestDbAsyncEnumerable(表达式);
} 
公共对象执行(表达式)
{ 
返回_inner.Execute(表达式);
} 
公共TResult执行(表达式)
{ 
返回_inner.Execute(表达式);
} 
公共任务ExecuteAsync(表达式表达式,CancellationToken CancellationToken)
{ 
返回Task.FromResult(执行(表达式));
} 
公共任务ExecuteAsync(表达式表达式,CancellationToken CancellationToken)
{ 
返回Task.FromResult(执行(表达式));
} 
} 
内部类TestDbAsyncEnumerable:EnumerableQuery、IDbAsyncEnumerable、IQueryable
{ 
公共TestDbAsyncEnumerable(IEnumerable enumerable)
:基本(可枚举)
{ } 
公共TestDbAsyncEnumerable(表达式)
:base(表达式)
{ } 
公共IDbAsyncEnumerator GetAsyncEnumerator()
{ 
返回新的TestDbAsyncEnumerator(this.AsEnumerable().GetEnumerator());
} 
IDBSyncEnumerator IDBSyncEnumeratable.GetAsyncEnumerator()
{ 
返回GetAsyncEnumerator();
} 
IQueryProvider IQueryable.Provider
{ 
获取{返回新的TestDbAsyncQueryProvider(this);}
} 
} 
内部类TestDbAsyncEnumerator:IDbAsyncEnumerator
{ 
私有只读IEnumerator\u内部;
公共TestDbAsyncEnumerator(IEnumerator内部)
{ 
_内部=内部;
} 
公共空间处置()
{ 
_depose();
} 
公共任务MoveNextAsync(CancellationToken CancellationToken)
{ 
返回Task.FromResult(_inner.MoveNext());
} 
公共电流
{ 
获取{return}inner.Current;}
} 
对象IDbAsyncEnumerator.Current
{ 
获取{返回当前;}
} 
} 
}
using System.Collections.Generic; 
using System.Data.Entity.Infrastructure; 
using System.Linq; 
using System.Linq.Expressions; 
using System.Threading; 
using System.Threading.Tasks; 

namespace TestingDemo 
{ 
    internal class TestDbAsyncQueryProvider<TEntity> : IDbAsyncQueryProvider 
    { 
        private readonly IQueryProvider _inner; 

        internal TestDbAsyncQueryProvider(IQueryProvider inner) 
        { 
            _inner = inner; 
        } 

        public IQueryable CreateQuery(Expression expression) 
        { 
            return new TestDbAsyncEnumerable<TEntity>(expression); 
        } 

        public IQueryable<TElement> CreateQuery<TElement>(Expression expression) 
        { 
            return new TestDbAsyncEnumerable<TElement>(expression); 
        } 

        public object Execute(Expression expression) 
        { 
            return _inner.Execute(expression); 
        } 

        public TResult Execute<TResult>(Expression expression) 
        { 
            return _inner.Execute<TResult>(expression); 
        } 

        public Task<object> ExecuteAsync(Expression expression, CancellationToken cancellationToken) 
        { 
            return Task.FromResult(Execute(expression)); 
        } 

        public Task<TResult> ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken) 
        { 
            return Task.FromResult(Execute<TResult>(expression)); 
        } 
    } 

    internal class TestDbAsyncEnumerable<T> : EnumerableQuery<T>, IDbAsyncEnumerable<T>, IQueryable<T> 
    { 
        public TestDbAsyncEnumerable(IEnumerable<T> enumerable) 
            : base(enumerable) 
        { } 

        public TestDbAsyncEnumerable(Expression expression) 
            : base(expression) 
        { } 

        public IDbAsyncEnumerator<T> GetAsyncEnumerator() 
        { 
            return new TestDbAsyncEnumerator<T>(this.AsEnumerable().GetEnumerator()); 
        } 

        IDbAsyncEnumerator IDbAsyncEnumerable.GetAsyncEnumerator() 
        { 
            return GetAsyncEnumerator(); 
        } 

        IQueryProvider IQueryable.Provider 
        { 
            get { return new TestDbAsyncQueryProvider<T>(this); } 
        } 
    } 

    internal class TestDbAsyncEnumerator<T> : IDbAsyncEnumerator<T> 
    { 
        private readonly IEnumerator<T> _inner; 

        public TestDbAsyncEnumerator(IEnumerator<T> inner) 
        { 
            _inner = inner; 
        } 

        public void Dispose() 
        { 
            _inner.Dispose(); 
        } 

        public Task<bool> MoveNextAsync(CancellationToken cancellationToken) 
        { 
            return Task.FromResult(_inner.MoveNext()); 
        } 

        public T Current 
        { 
            get { return _inner.Current; } 
        } 

        object IDbAsyncEnumerator.Current 
        { 
            get { return Current; } 
        } 
    } 
}