title: Using IAsyncEnumerable with Dapper
body: <p>We have recently migrated our ASP.NET Core API which uses <code>Dapper</code> to .NET Core 3.1. After the migration, we felt there was an opportunity to use the latest <code>IAsyncEnumerable</code> feature from <code>C# 8</code> for one of our endpoints.</p>
  
  <p>Here is the pseudocode before the changes:</p>
  
  <pre><code>public async Task&lt;IEnumerable&lt;Item&gt;&gt; GetItems(int id)
  {
      var reader = await _connection.QueryMultipleAsync(getItemsSql,
         param: new
         {
             Id = id
         });
  
      var idFromDb = (await reader.ReadAsync&lt;int?&gt;().ConfigureAwait(false)).SingleOrDefault();
      if (idFromDb == null)
      {
         return null;
      }
  
      var items = await reader.ReadAsync&lt;Item&gt;(buffered: false).ConfigureAwait(false);
  
      return Stream(reader, items);
  } 
  
  private IEnumerable&lt;Item&gt; Stream(SqlMapper.GridReader reader, IEnumerable&lt;Item&gt; items)
  {
      using (reader)
      {
          foreach (var item in items)
          {
              yield return item;
          }
      }     
  }
  </code></pre>
  
  <p>After <code>IAsyncEnumerable</code> code changes:</p>
  
  <pre><code>// Import Nuget pacakage: System.Linq.Async
  
  public async Task&lt;IAsyncEnumerable&lt;Item&gt;&gt; GetItems(int id)
  {
      var reader = await _connection.QueryMultipleAsync(getItemsSql,
         param: new
         {
             Id = id
         });
  
      var idFromDb = (await reader.ReadAsync&lt;int?&gt;().ConfigureAwait(false)).SingleOrDefault();
      if (idFromDb == null)
      {
          return null;
      }
  
      var items = await reader.ReadAsync&lt;Item&gt;(buffered: false).ConfigureAwait(false);
  
      return Stream(reader, items);
  } 
  
  private IAsyncEnumerable&lt;Item&gt; Stream(SqlMapper.GridReader reader, IEnumerable&lt;Item&gt; items)
  {
      using (reader)
      {
         await foreach (var item in items.ToAsyncEnumerable())
         {
             yield return item;
         }
      }
   }
  </code></pre>
  
  <p>The above approach is to use <code>ToAsyncEnumerable</code> is loosely inspired from <a href="https://anthonychu.ca/post/async-streams-dotnet-core-3-iasyncenumerable/" rel="noreferrer">this post</a>, but I'm not 100% sure if I'm using it in the right place/ context.</p>
  
  <p>Question:</p>
  
  <ul>
  <li>The dapper library only returns <code>IEnumerable</code> but can we use <code>ToAsyncEnumerable</code> to convert it into <code>IAsyncEnumerable</code> for <code>async</code> <code>stream</code> like above?</li>
  </ul>
  
  <p><strong>Note</strong>: This question looks similar to <a href="https://stackoverflow.com/questions/55536681/what-happens-with-returning-ienumerable-if-used-with-async-await-streaming-data">What happens with returning IEnumerable if used with async/await (streaming data from SQL Server with Dapper)?</a> but I do not think that answers my question.</p>