Why dapper return ToList() cannot be used in an async method?

asynchronous c# dapper

Question

I'm trying to change a method to make it async and using Dapper This is the current method in a repository class:

...
public class ClientsRepository : BaseRepository
    {
        public ClientsRepository(string connectionString): base (connectionString){  }
...

     public List<ClientSummaryModel> GetClientSummaryCredit(string id)
        {
            try
            {
                connection();
                con.Open();
                con.ChangeDatabase("PAQA");
                IList<ClientSummaryModel> SummaryClientList= SqlMapper.Query<ClientSummaryModel>(con, "dbo.SP_GET_CLIENT_SUMMARY '" + id + "','0','CREDIT'", CommandType.StoredProcedure).ToList();
                return SummaryClientList.ToList();

            }
            catch (Exception ex)
            {
                throw ex;
            }
            finally
            {
                con.Close();
            }
        }

I'm trying to make it async like this:

public async Task<List<ClientSummaryModel>> GetClientSummaryCredit(string id)
    {
        return await WithConnection(async c =>
        {
            c.ChangeDatabase("PAQA");
            IList<ClientSummaryModel> SummaryClientList= await c.QueryAsync<ClientSummaryModel>("dbo.SP_GET_CLIENT_SUMMARY '" + id + "','0','CREDIT'", CommandType.StoredProcedure).ToList();
            return SummaryClientList.ToList();
        });
    }

Unfortunately, I get the following error:

Cannot implicitly convert type 'System.Collections.Generic.IEnumerable' to 'System.Collections.Generic.IList'. An explicit conversion exists (are you missing a cast?)

What I need to change to return like the first method?

Additional info: Here it is a repository base class which i'm subclassing:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using System.Data;
using System.Data.SqlClient;
using Dapper;


namespace AutorizarCreditoApp.Repositories
{
    public abstract class BaseRepository
    {
        private readonly string _ConnectionString;

        protected BaseRepository(string connectionString)
        {
            _ConnectionString = connectionString;
        }

        protected async Task<T> WithConnection<T>(Func<IDbConnection, Task<T>> getData)
        {
            try
            {
                using (var connection = new SqlConnection(_ConnectionString))
                {
                    await connection.OpenAsync(); // Asynchronously open a connection to the database
                    return await getData(connection); // Asynchronously execute getData, which has been passed in as a Func<IDBConnection, Task<T>>
                }
            }
            catch (TimeoutException ex)
            {
                throw new Exception(String.Format("{0}.WithConnection() experienced a SQL timeout", GetType().FullName), ex);
            }
            catch (SqlException ex)
            {
                throw new Exception(String.Format("{0}.WithConnection() experienced a SQL exception (not a timeout)", GetType().FullName), ex);
            }
        }

    }
}
1
2
8/2/2016 9:29:28 PM

Popular Answer

I see two issues with your code sample.

First, just use .ToList() after the await. In other words, you don't need the .ToList() on the await line.

Second, please use a parameterized query -- Dapper supports it. You typically use an anonymously-typed object to declare the parameter values and pass that object as the param parameter. For stored procedures, it appears that you need to know the names of the parameters themselves rather than supplying them as part of the SQL. So, below, I presume that your stored procedure takes three parameters named @Id, @SomeNumber, and @CashOrCredit.

With these two suggestions, your code might look like this:

public async Task<List<ClientSummaryModel>> GetClientSummaryCredit(string id)
{
    return await WithConnection(async c =>
    {
        c.ChangeDatabase("PAQA");
        var summaryClientList =
            await c.QueryAsync<ClientSummaryModel>("dbo.SP_GET_CLIENT_SUMMARY",
                                                   new
                                                   {
                                                       Id = id,
                                                       SomeNumber = 0,
                                                       CashOrCredit = "CREDIT"
                                                   },
                                                   commandType: CommandType.StoredProcedure);
        return summaryClientList.ToList();
    });
}

Note: I presume that you are using System.Linq; in this file.

3
8/16/2016 12:50:18 PM


Related Questions





Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow