c# – ToArrayAsync()抛出“源IQueryable未实现IAsyncEnumerable”

c# – ToArrayAsync()抛出“源IQueryable未实现IAsyncEnumerable”,第1张

概述我在ASP.NET Core上有一个MVC项目,我的问题与IQueryable和异步相关.我在IQueryable< T>中编写了以下搜索方法: private IQueryable<InternalOrderInfo> WhereSearchTokens(IQueryable<InternalOrderInfo> query, SearchToken[] searchTokens){ 我在ASP.NET Core上有一个MVC项目,我的问题与Iqueryable和异步相关.我在Iqueryable< T>中编写了以下搜索方法:

private Iqueryable<InternalOrderInfo> WhereSearchTokens(Iqueryable<InternalOrderInfo> query,SearchToken[] searchTokens){    if (searchTokens.Length == 0)    {        return query;    }    var results = new List<InternalOrderInfo>();    foreach (var searchToken in searchTokens)    {        //search logic,intermediate results are being added to `results` using `AddRange()`    }    return results.Count != 0 ? results.distinct().Asqueryable() : query;}

我在方法ExecuteAsync()中调用它:

public async Task<GetAllinternalOrderInfoResponse> ExecuteAsync(GetAllinternalOrderInfoRequest request){    //rest of the code    if (searchTokens != null && searchTokens.Any())    {        allinternalOrderInfo = WhereSearchTokens(allinternalOrderInfo,searchTokens);    }    var orders = await allinternalOrderInfo.Skip(offset).Take(limit).ToArrayAsync();    //rest of the code}

当我测试这个时,我在线上得到一个InvalIDOperationException,我调用ToArrayAsync()

The source Iqueryable doesn’t implement IAsyncEnumerable. Only sources that implement IAsyncEnumerable can be used for Entity Framework asynchronous operations.

我已经将ToArrayAsync()更改为ToListAsync()但没有任何更改.我已经搜索了这个问题一段时间了,但已解决的问题主要与DbContext和实体创建有关.没有为此项目安装EntityFramework,最好不要因为应用程序架构而这样做.希望有人有任何想法在我的情况下做什么.

解决方法 如果您不打算改变您的设计 – 您有以下几种选择:

1)将Asqueryable更改为另一个返回Iqueryable的方法,该方法也实现了IDbAsyncEnumerable.例如,您可以扩展Enumerablequery(由Asqueryable返回):

public class AsyncEnumerablequery<T> : Enumerablequery<T>,IDbAsyncEnumerable<T> {    public AsyncEnumerablequery(IEnumerable<T> enumerable) : base(enumerable) {    }    public AsyncEnumerablequery(Expression Expression) : base(Expression) {    }    public IDbAsyncEnumerator<T> GetAsyncEnumerator() {        return new InMemoryDbAsyncEnumerator<T>(((IEnumerable<T>) this).GetEnumerator());    }    IDbAsyncEnumerator IDbAsyncEnumerable.GetAsyncEnumerator() {        return GetAsyncEnumerator();    }    private class InMemoryDbAsyncEnumerator<T> : IDbAsyncEnumerator<T> {        private Readonly IEnumerator<T> _enumerator;        public InMemoryDbAsyncEnumerator(IEnumerator<T> enumerator) {            _enumerator = enumerator;        }        public voID dispose() {        }        public Task<bool> MoveNextAsync(CancellationToken cancellationToken) {            return Task.Fromresult(_enumerator.MoveNext());        }        public T Current => _enumerator.Current;        object IDbAsyncEnumerator.Current => Current;    }}

然后你改变

results.distinct().Asqueryable()

new AsyncEnumerablequery<InternalOrderInfo>(results.distinct())

之后,ToArrayAsync将不再抛出异常(显然你可以像Asqueryable一样创建自己的扩展方法).

2)更改ToArrayAsync部分:

public static class EfExtensions {    public static Task<TSource[]> ToArrayAsyncSafe<TSource>(this Iqueryable<TSource> source) {        if (source == null)            throw new ArgumentNullException(nameof(source));        if (!(source is IDbAsyncEnumerable<TSource>))            return Task.Fromresult(source.ToArray());        return source.ToArrayAsync();    }}

并使用ToArrayAsyncSafe而不是ToArrayAsync,如果Iqueryable不是IDbAsyncEnumerable,它将回退到同步枚举.在你的情况下,这只发生在查询真的是内存列表而不是查询时,所以异步执行无论如何都没有意义.

总结

以上是内存溢出为你收集整理的c# – ToArrayAsync()抛出“源IQueryable未实现IAsyncEnumerable”全部内容,希望文章能够帮你解决c# – ToArrayAsync()抛出“源IQueryable未实现IAsyncEnumerable”所遇到的程序开发问题。

如果觉得内存溢出网站内容还不错,欢迎将内存溢出网站推荐给程序员好友。

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/1221188.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-06-05
下一篇 2022-06-05

发表评论

登录后才能评论

评论列表(0条)

保存