Skip to content

Instantly share code, notes, and snippets.

@imgen
Created September 20, 2019 08:16
Show Gist options
  • Save imgen/8b2f140c9340230a61de9a84a272171d to your computer and use it in GitHub Desktop.
Save imgen/8b2f140c9340230a61de9a84a272171d to your computer and use it in GitHub Desktop.
/// <summary>
/// Adapted from SO answer https://stackoverflow.com/a/40491640/915147
/// </summary>
/// <typeparam name="TEntity"></typeparam>
public class AsyncQueryProvider<TEntity> : IAsyncQueryProvider
{
private readonly IQueryProvider _inner;
internal AsyncQueryProvider(IQueryProvider inner) => _inner = inner;
public IQueryable CreateQuery(Expression expression) =>
new AsyncEnumerableQuery<TEntity>(expression);
public IQueryable<TElement> CreateQuery<TElement>(Expression expression) =>
new AsyncEnumerableQuery<TElement>(expression);
public object Execute(Expression expression) => _inner.Execute(expression);
public TResult Execute<TResult>(Expression expression) =>
_inner.Execute<TResult>(expression);
public IAsyncEnumerable<TResult> ExecuteAsync<TResult>(Expression expression) => new AsyncEnumerableQuery<TResult>(expression);
public Task<TResult> ExecuteAsync<TResult>(Expression expression, CancellationToken cancellationToken) => Task.FromResult(Execute<TResult>(expression));
}
public class AsyncEnumerableQuery<T> : EnumerableQuery<T>, IAsyncEnumerable<T>, IQueryable<T>
{
public AsyncEnumerableQuery(IEnumerable<T> enumerable)
: base(enumerable)
{ }
public AsyncEnumerableQuery(Expression expression)
: base(expression)
{ }
public IAsyncEnumerator<T> GetEnumerator() => new AsyncEnumerator<T>(this.AsEnumerable().GetEnumerator());
IQueryProvider IQueryable.Provider => new AsyncQueryProvider<T>(this);
}
public class AsyncEnumerator<T> : IAsyncEnumerator<T>
{
private readonly IEnumerator<T> _inner;
public AsyncEnumerator(IEnumerator<T> inner) => _inner = inner;
public void Dispose() => _inner.Dispose();
public T Current => _inner.Current;
public Task<bool> MoveNext(CancellationToken cancellationToken) =>
Task.FromResult(_inner.MoveNext());
}
public static class AsyncEnumerableQueryExtensions
{
public static AsyncEnumerableQuery<T> AsAsyncQueryable<T>(this IEnumerable<T> sequence)
=> new AsyncEnumerableQuery<T>(sequence);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment