Node.JS
Node.JS

Reputation: 1592

Empty IQueryable that implements IAsyncEnumerable

I am looking for an empty IQueryable<T> that implements IAsyncEnumerable<T>. My current code does not work because empty Enumerable does not implement IAsyncEnumerable<T>. Thanks for any help or hint.

I have the following design:

var result = Enumerable.Empty<Foo>().AsQueryable();  // Not working!

if (condition1)
{
    IQueryable<Foo> part1 = ....;

    result = result.Concat(part1);
}

if (condition2)
{
    IQueryable<Foo> part2 = ....;

    result = result.Concat(part2);
}

return await result.ToListAsync();

Error message:

The source IQueryable doesn't implement IAsyncEnumerable<Foo>. Only sources that implement IAsyncEnumerable can be used for Entity Framework asynchronous operations.
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.AsAsyncEnumerable[TSource](IQueryable`1 source)
   at Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListAsync[TSource](IQueryable`1 source, CancellationToken cancellationToken)

Upvotes: 4

Views: 9071

Answers (2)

Amir Popovich
Amir Popovich

Reputation: 29846

Use the nuget package System.Linq.Async to get the ToAsyncEnumerable() method:

private static async Task<List<Foo>> GetList()
{
    var result = Enumerable.Empty<Foo>().AsQueryable();

    if (true)
    {
        IQueryable<Foo> part1 = new List<Foo> { new Foo() }.AsQueryable();
        result = result.Concat(part1);
    }

    if (true)
    {
        IQueryable<Foo> part2 = new List<Foo> { new Foo(), new Foo() }.AsQueryable();
        result = result.Concat(part2);
    }

    return await result.ToAsyncEnumerable().ToListAsync();
}

Upvotes: 5

Pavel Shastov
Pavel Shastov

Reputation: 3037

You can create an empty IAsyncEnumerable as it is described in this SO.

But if I don't think it is an ideal option since it requires referencing an additional package or implementing AsyncEnumerable.Empty on your own.

Alternatively, you could change your code in a way that does not require an "empty" container for your expressions.

For example:

var expressions = new List<IQueryable<Foo>>();

if (condition1)
{
    IQueryable<Foo> part1 = ....;

    expressions.Add(part1);
}

if (condition2)
{
    IQueryable<Foo> part2 = ....;

    expressions.Add(part2);
}

var result = expressions.Aggregate((acc, i) => acc.Concat(i));

return await result.ToListAsync();

Upvotes: 1

Related Questions