/// <summary>
/// Get all columns for a certain table
/// </summary>
public async Task<List<Tuple<string, string, int?>>> GetAllColumnsFromTableAsync(string tableName)
{
List<Tuple<string, string, int?>> result;
string query = "SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME= @tableName";
using (IDbConnection db = DbConnection)
{
IEnumerable<Tuple<string, string, int?>> queryOutput = await db.QueryAsync<string, string, int?, Tuple<string, string, int?>>
(query, Tuple.Create, new { tableName = tableName }, null, false, splitOn: "*");
result = queryOutput.ToList(); // System.InvalidOperationException: Invalid attempt to call FieldCount when reader is closed.
}
if (result is not null && result.Count > 0)
{
return result;
}
else
{
return default;
}
}
ref: https://github.com/DapperLib/Dapper/issues/745
update:
when replacing the tuple with named tuples the query in itself works.
public async Task<List<(string COLUMN_NAME, string DATA_TYPE, int? CHARACTER_MAXIMUM_LENGTH)>> GetAllColumnsFromTableAsync2(string tableName)
{
const string query = "SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME= @tableName";
using var connection = new SqlConnection(_connectionstring);
var output = await connection.QueryAsync<(string COLUMN_NAME, string DATA_TYPE, int? CHARACTER_MAXIMUM_LENGTH)>
(query, new { tableName = tableName });
return output.ToList();
}
I have a further problem but that is another question.
Dapper's supposed to make your life easier, and that code looks complicated.
If you use a Tuple with named fields, you can just use Dapper's auto mapping to materialize. EG:
static class DbExtensions
{
public static async Task<List<(string COLUMN_NAME, string DATA_TYPE, int? CHARACTER_MAXIMUM_LENGTH)>> GetAllColumnsFromTableAsync(this IDbConnection db, string tableName, string schema = "dbo")
{
string query = "SELECT COLUMN_NAME, DATA_TYPE, CHARACTER_MAXIMUM_LENGTH FROM INFORMATION_SCHEMA.COLUMNS WHERE TABLE_NAME= @tableName and TABLE_SCHEMA=@schema";
var queryOutput = await db.QueryAsync<(string COLUMN_NAME, string DATA_TYPE, int? CHARACTER_MAXIMUM_LENGTH)>(query, new { tableName = tableName, schema = schema });
return queryOutput.ToList();
}
}
Also note there's a bug in your query if you have multiple tables with the same name, so you should specify the schema.