2

I am fairly new to C# and Dapper. I am trying to write a generic Insert Data method for my project. I come from a Delphi environment so I am still finding my way around C#.

Dapper seems fairly straight forward to use but I am experiencing some challenges. I have tried every which way to get the syntax right with the following code but have been unsuccessful.

Issues seem to be around the T (I still quite don't understand what T is) and all the combinations I have tried don't work.

public async Task<int> InsertData<T>(T list)
{
    string connectionString = _config.GetConnectionString(ConnectionStringName);

    using (IDbConnection connection = new SqlConnection(connectionString))
    {
        return await connection.InsertAsync<int>(list);
    }
}

The following code does work, so where am I going wrong?

public async Task SaveData<T>(string sql, T parameters)
{
    string connectionString = _config.GetConnectionString(ConnectionStringName);

    using (IDbConnection connection = new SqlConnection(connectionString))
    {
            await connection.ExecuteAsync(sql, parameters);
    }
}
Amit Joshi
  • 15,448
  • 21
  • 77
  • 141

1 Answers1

3

Your second code (await connection.ExecuteAsync(sql, parameters);) works because you are simply executing your hand written SQL statement. The method ExecuteAsync belongs to Dapper; NOT Dapper.Contrib. The generic T is used for parameters, not for the object you are trying to insert.

With your first code (return await connection.InsertAsync<int>(list);), you are actually using Dapper.Contrib; you are not writing the SQL statement by hand. Dapper.Contrib generates it for you.

Your following code seems the problem:

return await connection.InsertAsync<int>(list);

You are passing generic parameter <int> to the method which does not make sense.

I have not tested this but I hope changing that line to below one should work:

return await connection.InsertAsync<T>(list);

Also, you have to make sure the generic type T is class by adding where T : class to it.

Following generic method should serve your purpose; you need to convert it to async to match with your current code:

public void InsertData<T>(T entity) where T : class
{
    string connectionString = ....;

    using(IDbConnection connection = new SqlConnection(connectionString))
    {
        long result = connection.Insert<T>(entity);
    }
}

I did not understood few other parts in your code. Say InsertData<T>(T list). What is list? Is it as single object or list of objects? If it is list of objects, List<T> list makes more sense. If it is single object, better you rename list to actual object name, say T customer/entity/poco etc.

Amit Joshi
  • 15,448
  • 21
  • 77
  • 141