将IQueryable <T>转换为IAsyncEnumerable <T>的潜在问题

时间:2019-10-18 11:00:17

标签: c# entity-framework

在对await的过度使用情况进行了this article的阅读之后,我决定在可能的地方删除等待。由于两个原因,这导致我的数据服务出现问题:

  1. 所有检索集合的方法均按约定返回Task<IEnumerable<T>>
  2. EF不提供ToEnumerableAsync

现在,当我删除await时,编译器将不再展开Task对象,而我会遇到编译错误,该错误表明Task<List<T>>无法转换为Task<IEnumerable<T>>

因此,我着手创建自己的ToEnumerableAsnyc。 “ PoC”版本如下所示:

public static IEnumerable<T> ToEnumerableAsync<T>(this IQueryable<T> source)
    => (await source.ToListAsync()).AsEnumerable();

但是,这只会包裹多余的await而不会将其删除,也就是说,仍然有我的awaitToListAsync内部使用的那个。从以上链接的文章来看,这会产生不必要的开销。这不是什么大问题,但仍然是开销。如果我错了,请纠正我:)

因此,我着手查找Microsoft开发人员如何在 ASP.NET Core 2.2 中实现ToListAsync,并且设法创建了自己的ToEnumerableAsync实现。根据他们的解决方案不使用await。看起来就是这样:

public static Task<IEnumerable<T>> ToEnumerableAsync<T>(this IQueryable<T> queryable)
{
    var asyncEnum = AsAsyncEnumerable(queryable);
    var list = new List<T>();

    return asyncEnum.Aggregate(
        (IEnumerable<T>)list,
        (list, x) =>
        {
            ((List<T>)list).Add(x);
            return list;
        });
}

private static IAsyncEnumerable<T> AsAsyncEnumerable<T>(this IQueryable<T> queryable)
{
    if (queryable is IAsyncEnumerable<T> asyncEnumerable)
    {
        return asyncEnumerable;
    }

    throw new InvalidOperationException(
        $"Cannot cast \"IQueryable\" to \"IAsyncEnumerable\". Type: \"{typeof(T).FullName}\"");
}

最后是我的问题:开发人员将显露的IQueryable<T>强制转换为IAsyncEnumerable<T>InvalidOperationExeption会导致什么问题? IQueryable<T>如何以及为何无法转换为IAsyncEnumerable<T>

原始EF文件:QueriableExtensions.cs

0 个答案:

没有答案