Sean
Sean

Reputation: 31

CosmosDB Dotnet - Get All Items in a container

I am trying to work out the simplest way to get all items in a container. I have seen a couple of ways of doing it that all seem more complex than it should be. Any ideas?

public async Task<IEnumerable<T>> ListAsync()
{
    return _container.//Something
}

I'm hoping something as simple as this GetAsync method exists.

public async Task<T> GetAsync(Guid id)
{
    return await _container.ReadItemAsync<T>(id.ToString(), new PartitionKey(id.ToString()));
}

Thanks! :)

Upvotes: 3

Views: 3008

Answers (1)

TheGeneral
TheGeneral

Reputation: 81513

You can use GetItemQueryIterator in an IAsyncEnumerable

This method creates a query for items under a container in an Azure Cosmos database using a SQL statement with parameterized values. It returns a FeedIterator. For more information on preparing SQL statements with parameterized values,

Example

//Some Query
public static async IAsyncEnumerable<T> GetAllAsync<T>(string query) 
{ 
   var definition = new QueryDefinition(query);
   var iterator = _container.GetItemQueryIterator<T>(definition);

   while (iterator.HasMoreResults)
      foreach (var item in await iterator.ReadNextAsync().ConfigureAwait(false))
         yield return item;
}

Or you can supply null or an empty parameter list to GetItemQueryIterator

public static async IAsyncEnumerable<T> GetAllAsync<T>() 
{ 
   var iterator = _container.GetItemQueryIterator<T>();

   while (iterator.HasMoreResults)
      foreach (var item in await iterator.ReadNextAsync().ConfigureAwait(false))
         yield return item;
}

Usages

await foreach (var item in GetAllAsync<Bob>())
   Console.WriteLine(item);

If you install the System.Linq.Async nuget you can call ToListAsync

var results = await GetAllAsync<Bob>().ToListAsync();

If you don't want to take a dependency, you can roll your own

public static class Extensions
{
   public static ValueTask<List<TSource>> ToListAsync<TSource>(
      this IAsyncEnumerable<TSource> source, 
      CancellationToken cancellationToken = default)
   {
      if (source is null) throw new ArgumentNullException(nameof(source));

      return Local(source, cancellationToken);

      static async ValueTask<List<TSource>> Local(IAsyncEnumerable<TSource> source, CancellationToken cancellationToken)
      {
         var list = new List<TSource>();
         await foreach (var item in source.WithCancellation(cancellationToken).ConfigureAwait(false))
            list.Add(item);
         return list;
      }
   }
}

Upvotes: 5

Related Questions