diff --git a/Dapper/SqlMapper.Async.cs b/Dapper/SqlMapper.Async.cs index 4b2ffe9db2a49d11504274de92689bbf88ddb7b0..01d62f4601aefcc19f7b8344fe8b2234fd13ff2e 100644 --- a/Dapper/SqlMapper.Async.cs +++ b/Dapper/SqlMapper.Async.cs @@ -16,94 +16,141 @@ public static partial class SqlMapper /// /// Execute a query asynchronously using .NET 4.5 Task. /// + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. /// Note: each row can be accessed via "dynamic", or by casting to an IDictionary<string,object> - public static Task> QueryAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) - { - return QueryAsync(cnn, typeof(DapperRow), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered, default(CancellationToken))); - } + public static Task> QueryAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryAsync(cnn, typeof(DapperRow), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered, default(CancellationToken))); /// /// Execute a query asynchronously using .NET 4.5 Task. /// + /// The connection to query on. + /// The command used to query on this connection. /// Note: each row can be accessed via "dynamic", or by casting to an IDictionary<string,object> - public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command) - { - return QueryAsync(cnn, typeof(DapperRow), command); - } + public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command) => + QueryAsync(cnn, typeof(DapperRow), command); /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// + /// The connection to query on. + /// The command used to query on this connection. /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> - public static Task QueryFirstAsync(this IDbConnection cnn, CommandDefinition command) - { - return QueryRowAsync(cnn, Row.First, typeof(DapperRow), command); - } + public static Task QueryFirstAsync(this IDbConnection cnn, CommandDefinition command) => + QueryRowAsync(cnn, Row.First, typeof(DapperRow), command); + /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// + /// The connection to query on. + /// The command used to query on this connection. /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> - public static Task QueryFirstOrDefaultAsync(this IDbConnection cnn, CommandDefinition command) - { - return QueryRowAsync(cnn, Row.FirstOrDefault, typeof(DapperRow), command); - } + public static Task QueryFirstOrDefaultAsync(this IDbConnection cnn, CommandDefinition command) => + QueryRowAsync(cnn, Row.FirstOrDefault, typeof(DapperRow), command); + /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// + /// The connection to query on. + /// The command used to query on this connection. /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> - public static Task QuerySingleAsync(this IDbConnection cnn, CommandDefinition command) - { - return QueryRowAsync(cnn, Row.Single, typeof(DapperRow), command); - } + public static Task QuerySingleAsync(this IDbConnection cnn, CommandDefinition command) => + QueryRowAsync(cnn, Row.Single, typeof(DapperRow), command); + /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// + /// The connection to query on. + /// The command used to query on this connection. /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> - public static Task QuerySingleOrDefaultAsync(this IDbConnection cnn, CommandDefinition command) - { - return QueryRowAsync(cnn, Row.SingleOrDefault, typeof(DapperRow), command); - } + public static Task QuerySingleOrDefaultAsync(this IDbConnection cnn, CommandDefinition command) => + QueryRowAsync(cnn, Row.SingleOrDefault, typeof(DapperRow), command); /// /// Execute a query asynchronously using .NET 4.5 Task. /// - public static Task> QueryAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) - { - return QueryAsync(cnn, typeof(T), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered, default(CancellationToken))); - } + /// The type of results to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// + /// A sequence of data of ; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). + /// + public static Task> QueryAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryAsync(cnn, typeof(T), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered, default(CancellationToken))); /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// - public static Task QueryFirstAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) - { - return QueryRowAsync(cnn, Row.First, typeof(T), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); - } + /// The type of result to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + public static Task QueryFirstAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryRowAsync(cnn, Row.First, typeof(T), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); + /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// - public static Task QueryFirstOrDefaultAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) - { - return QueryRowAsync(cnn, Row.FirstOrDefault, typeof(T), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); - } + /// The type of result to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + public static Task QueryFirstOrDefaultAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryRowAsync(cnn, Row.FirstOrDefault, typeof(T), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); + /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// - public static Task QuerySingleAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) - { - return QueryRowAsync(cnn, Row.Single, typeof(T), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); - } + /// The type of result to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + public static Task QuerySingleAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryRowAsync(cnn, Row.Single, typeof(T), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); + /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// - public static Task QuerySingleOrDefaultAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) - { - return QueryRowAsync(cnn, Row.SingleOrDefault, typeof(T), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); - } + /// The type to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + public static Task QuerySingleOrDefaultAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryRowAsync(cnn, Row.SingleOrDefault, typeof(T), new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None, default(CancellationToken))); /// /// Execute a query asynchronously using .NET 4.5 Task. /// + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. public static Task> QueryAsync(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { if (type == null) throw new ArgumentNullException(nameof(type)); @@ -113,6 +160,14 @@ public static Task> QueryAsync(this IDbConnection cnn, Type /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. public static Task QueryFirstAsync(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { if (type == null) throw new ArgumentNullException(nameof(type)); @@ -121,6 +176,14 @@ public static Task QueryFirstAsync(this IDbConnection cnn, Type type, st /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. public static Task QueryFirstOrDefaultAsync(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { if (type == null) throw new ArgumentNullException(nameof(type)); @@ -129,6 +192,14 @@ public static Task QueryFirstOrDefaultAsync(this IDbConnection cnn, Type /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. public static Task QuerySingleAsync(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { if (type == null) throw new ArgumentNullException(nameof(type)); @@ -137,6 +208,14 @@ public static Task QuerySingleAsync(this IDbConnection cnn, Type type, s /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. public static Task QuerySingleOrDefaultAsync(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { if (type == null) throw new ArgumentNullException(nameof(type)); @@ -146,81 +225,103 @@ public static Task QuerySingleOrDefaultAsync(this IDbConnection cnn, Typ /// /// Execute a query asynchronously using .NET 4.5 Task. /// - public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command) - { - return QueryAsync(cnn, typeof(T), command); - } + /// The type to return. + /// The connection to query on. + /// The command used to query on this connection. + /// + /// A sequence of data of ; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). + /// + public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command) => + QueryAsync(cnn, typeof(T), command); /// /// Execute a query asynchronously using .NET 4.5 Task. /// - public static Task> QueryAsync(this IDbConnection cnn, Type type, CommandDefinition command) - { - return QueryAsync(cnn, type, command); - } + /// The connection to query on. + /// The type to return. + /// The command used to query on this connection. + public static Task> QueryAsync(this IDbConnection cnn, Type type, CommandDefinition command) => + QueryAsync(cnn, type, command); + /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// - public static Task QueryFirstAsync(this IDbConnection cnn, Type type, CommandDefinition command) - { - return QueryRowAsync(cnn, Row.First, type, command); - } + /// The connection to query on. + /// The type to return. + /// The command used to query on this connection. + public static Task QueryFirstAsync(this IDbConnection cnn, Type type, CommandDefinition command) => + QueryRowAsync(cnn, Row.First, type, command); + /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// - public static Task QueryFirstAsync(this IDbConnection cnn, CommandDefinition command) - { - return QueryRowAsync(cnn, Row.First, typeof(T), command); - } + /// The type to return. + /// The connection to query on. + /// The command used to query on this connection. + public static Task QueryFirstAsync(this IDbConnection cnn, CommandDefinition command) => + QueryRowAsync(cnn, Row.First, typeof(T), command); + /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// - public static Task QueryFirstOrDefaultAsync(this IDbConnection cnn, Type type, CommandDefinition command) - { - return QueryRowAsync(cnn, Row.FirstOrDefault, type, command); - } + /// The connection to query on. + /// The type to return. + /// The command used to query on this connection. + public static Task QueryFirstOrDefaultAsync(this IDbConnection cnn, Type type, CommandDefinition command) => + QueryRowAsync(cnn, Row.FirstOrDefault, type, command); + /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// - public static Task QueryFirstOrDefaultAsync(this IDbConnection cnn, CommandDefinition command) - { - return QueryRowAsync(cnn, Row.FirstOrDefault, typeof(T), command); - } + /// The type to return. + /// The connection to query on. + /// The command used to query on this connection. + public static Task QueryFirstOrDefaultAsync(this IDbConnection cnn, CommandDefinition command) => + QueryRowAsync(cnn, Row.FirstOrDefault, typeof(T), command); + /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// - public static Task QuerySingleAsync(this IDbConnection cnn, Type type, CommandDefinition command) - { - return QueryRowAsync(cnn, Row.Single, type, command); - } + /// The connection to query on. + /// The type to return. + /// The command used to query on this connection. + public static Task QuerySingleAsync(this IDbConnection cnn, Type type, CommandDefinition command) => + QueryRowAsync(cnn, Row.Single, type, command); + /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// - public static Task QuerySingleAsync(this IDbConnection cnn, CommandDefinition command) - { - return QueryRowAsync(cnn, Row.Single, typeof(T), command); - } + /// The type to return. + /// The connection to query on. + /// The command used to query on this connection. + public static Task QuerySingleAsync(this IDbConnection cnn, CommandDefinition command) => + QueryRowAsync(cnn, Row.Single, typeof(T), command); + /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// - public static Task QuerySingleOrDefaultAsync(this IDbConnection cnn, Type type, CommandDefinition command) - { - return QueryRowAsync(cnn, Row.SingleOrDefault, type, command); - } + /// The connection to query on. + /// The type to return. + /// The command used to query on this connection. + public static Task QuerySingleOrDefaultAsync(this IDbConnection cnn, Type type, CommandDefinition command) => + QueryRowAsync(cnn, Row.SingleOrDefault, type, command); + /// /// Execute a single-row query asynchronously using .NET 4.5 Task. /// - public static Task QuerySingleOrDefaultAsync(this IDbConnection cnn, CommandDefinition command) - { - return QueryRowAsync(cnn, Row.SingleOrDefault, typeof(T), command); - } + /// The type to return. + /// The connection to query on. + /// The command used to query on this connection. + public static Task QuerySingleOrDefaultAsync(this IDbConnection cnn, CommandDefinition command) => + QueryRowAsync(cnn, Row.SingleOrDefault, typeof(T), command); private static Task ExecuteReaderWithFlagsFallbackAsync(DbCommand cmd, bool wasClosed, CommandBehavior behavior, CancellationToken cancellationToken) { var task = cmd.ExecuteReaderAsync(GetBehavior(wasClosed, behavior), cancellationToken); if (task.Status == TaskStatus.Faulted && Settings.DisableCommandBehaviorOptimizations(behavior, task.Exception.InnerException)) { // we can retry; this time it will have different flags - task = cmd.ExecuteReaderAsync(GetBehavior(wasClosed, behavior), cancellationToken); + return cmd.ExecuteReaderAsync(GetBehavior(wasClosed, behavior), cancellationToken); } return task; } @@ -252,7 +353,7 @@ private static async Task> QueryAsync(this IDbConnection cnn, if (command.Buffered) { - List buffer = new List(); + var buffer = new List(); var convertToType = Nullable.GetUnderlyingType(effectiveType) ?? effectiveType; while (await reader.ReadAsync(cancel).ConfigureAwait(false)) { @@ -266,7 +367,7 @@ private static async Task> QueryAsync(this IDbConnection cnn, buffer.Add((T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture)); } } - while (await reader.NextResultAsync(cancel).ConfigureAwait(false)) { } + while (await reader.NextResultAsync(cancel).ConfigureAwait(false)) { /* ignore subsequent result sets */ } command.OnCompleted(); return buffer; } @@ -281,7 +382,7 @@ private static async Task> QueryAsync(this IDbConnection cnn, } finally { - using (reader) { } // dispose if non-null + using (reader) { /* dispose if non-null */ } if (wasClosed) cnn.Close(); } } @@ -328,18 +429,18 @@ private static async Task QueryRowAsync(this IDbConnection cnn, Row row, T result = (T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture); } if ((row & Row.Single) != 0 && await reader.ReadAsync(cancel).ConfigureAwait(false)) ThrowMultipleRows(row); - while (await reader.ReadAsync(cancel).ConfigureAwait(false)) { } + while (await reader.ReadAsync(cancel).ConfigureAwait(false)) { /* ignore rows after the first */ } } else if ((row & Row.FirstOrDefault) == 0) // demanding a row, and don't have one { ThrowZeroRows(row); } - while (await reader.NextResultAsync(cancel).ConfigureAwait(false)) { } + while (await reader.NextResultAsync(cancel).ConfigureAwait(false)) { /* ignore result sets after the first */ } return result; } finally { - using (reader) { } // dispose if non-null + using (reader) { /* dispose if non-null */ } if (wasClosed) cnn.Close(); } } @@ -348,14 +449,22 @@ private static async Task QueryRowAsync(this IDbConnection cnn, Row row, T /// /// Execute a command asynchronously using .NET 4.5 Task. /// - public static Task ExecuteAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) - { - return ExecuteAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered, default(CancellationToken))); - } + /// The connection to query on. + /// The SQL to execute for this query. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// The number of rows affected. + public static Task ExecuteAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + ExecuteAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered, default(CancellationToken))); /// /// Execute a command asynchronously using .NET 4.5 Task. /// + /// The connection to execute on. + /// The command to execute on this connection. + /// The number of rows affected. public static Task ExecuteAsync(this IDbConnection cnn, CommandDefinition command) { object param = command.Parameters; @@ -429,16 +538,17 @@ private static async Task ExecuteMultiImplAsync(IDbConnection cnn, CommandD while (pending.Count != 0) { var pair = pending.Dequeue(); - using (pair.Command) { } // dispose commands + using (pair.Command) { /* dispose commands */ } total += await pair.Task.ConfigureAwait(false); } - } finally + } + finally { // this only has interesting work to do if there are failures - using (cmd) { } // dispose commands + using (cmd) { /* dispose commands */ } while (pending.Count != 0) { // dispose tasks even in failure - using (pending.Dequeue().Command) { } // dispose commands + using (pending.Dequeue().Command) { /* dispose commands */ } } } } @@ -497,175 +607,250 @@ private static async Task ExecuteImplAsync(IDbConnection cnn, CommandDefini } /// - /// Maps a query to objects + /// Perform a asynchronous multi-mapping query with 2 input types. + /// This returns a single type, combined from the raw types via . /// - /// The first type in the recordset - /// The second type in the recordset - /// The return type - /// - /// - /// - /// - /// - /// - /// The field we should split and read the second object from (default: id) - /// Number of seconds before command execution timeout + /// The first type in the recordset. + /// The second type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. /// Is it a stored proc or a batch? - /// - public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) - { - return MultiMapAsync(cnn, + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMapAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None, default(CancellationToken)), map, splitOn); - } /// - /// Maps a query to objects + /// Perform a asynchronous multi-mapping query with 2 input types. + /// This returns a single type, combined from the raw types via . /// - /// The first type in the recordset - /// The second type in the recordset - /// The return type - /// - /// The field we should split and read the second object from (default: id) - /// The command to execute - /// - /// - public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") - { - return MultiMapAsync(cnn, command, map, splitOn); - } + /// The first type in the recordset. + /// The second type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The field we should split and read the second object from (default: "Id"). + /// The command to execute. + /// The function to map row types to the return type. + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") => + MultiMapAsync(cnn, command, map, splitOn); /// - /// Maps a query to objects - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// The Field we should split and read the second object from (default: id) - /// Number of seconds before command execution timeout - /// - /// - public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) - { - return MultiMapAsync(cnn, + /// Perform a asynchronous multi-mapping query with 3 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMapAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None, default(CancellationToken)), map, splitOn); - } /// - /// Maps a query to objects + /// Perform a asynchronous multi-mapping query with 3 input types. + /// This returns a single type, combined from the raw types via . /// - /// - /// - /// - /// - /// - /// The field we should split and read the second object from (default: id) - /// The command to execute - /// - /// - public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") - { - return MultiMapAsync(cnn, command, map, splitOn); - } + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The field we should split and read the second object from (default: "Id"). + /// The command to execute. + /// The function to map row types to the return type. + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") => + MultiMapAsync(cnn, command, map, splitOn); /// - /// Perform a multi mapping query with 4 input parameters - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) - { - return MultiMapAsync(cnn, + /// Perform a asynchronous multi-mapping query with 4 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMapAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None, default(CancellationToken)), map, splitOn); - } /// - /// Perform a multi mapping query with 4 input parameters + /// Perform a asynchronous multi-mapping query with 4 input types. + /// This returns a single type, combined from the raw types via . /// - /// - /// - /// - /// - /// - /// - /// The field we should split and read the second object from (default: id) - /// The command to execute - /// - /// - public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") - { - return MultiMapAsync(cnn, command, map, splitOn); - } + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The field we should split and read the second object from (default: "Id"). + /// The command to execute. + /// The function to map row types to the return type. + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") => + MultiMapAsync(cnn, command, map, splitOn); /// - /// Perform a multi mapping query with 5 input parameters + /// Perform a asynchronous multi-mapping query with 5 input types. + /// This returns a single type, combined from the raw types via . /// - public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) - { - return MultiMapAsync(cnn, + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMapAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None, default(CancellationToken)), map, splitOn); - } /// - /// Perform a multi mapping query with 5 input parameters + /// Perform a asynchronous multi-mapping query with 5 input types. + /// This returns a single type, combined from the raw types via . /// - public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") - { - return MultiMapAsync(cnn, command, map, splitOn); - } + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The field we should split and read the second object from (default: "Id"). + /// The command to execute. + /// The function to map row types to the return type. + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") => + MultiMapAsync(cnn, command, map, splitOn); /// - /// Perform a multi mapping query with 6 input parameters + /// Perform a asynchronous multi-mapping query with 6 input types. + /// This returns a single type, combined from the raw types via . /// - public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) - { - return MultiMapAsync(cnn, + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The sixth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMapAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None, default(CancellationToken)), map, splitOn); - } /// - /// Perform a multi mapping query with 6 input parameters + /// Perform a asynchronous multi-mapping query with 6 input types. + /// This returns a single type, combined from the raw types via . /// - public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") - { - return MultiMapAsync(cnn, command, map, splitOn); - } + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The sixth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The field we should split and read the second object from (default: "Id"). + /// The command to execute. + /// The function to map row types to the return type. + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") => + MultiMapAsync(cnn, command, map, splitOn); /// - /// Perform a multi mapping query with 7 input parameters + /// Perform a asynchronous multi-mapping query with 7 input types. + /// This returns a single type, combined from the raw types via . /// - public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) - { - return MultiMapAsync(cnn, + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The sixth type in the recordset. + /// The seventh type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMapAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None, default(CancellationToken)), map, splitOn); - } /// - /// Perform a multi mapping query with 7 input parameters + /// Perform an asynchronous multi-mapping query with 7 input types. + /// This returns a single type, combined from the raw types via . /// - public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") - { - return MultiMapAsync(cnn, command, map, splitOn); - } + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The sixth type in the recordset. + /// The seventh type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The field we should split and read the second object from (default: "Id"). + /// The command to execute. + /// The function to map row types to the return type. + /// An enumerable of . + public static Task> QueryAsync(this IDbConnection cnn, CommandDefinition command, Func map, string splitOn = "Id") => + MultiMapAsync(cnn, command, map, splitOn); private static async Task> MultiMapAsync(this IDbConnection cnn, CommandDefinition command, Delegate map, string splitOn) { @@ -683,31 +868,33 @@ private static async Task ExecuteImplAsync(IDbConnection cnn, CommandDefini var results = MultiMapImpl(null, CommandDefinition.ForCallback(command.Parameters), map, splitOn, reader, identity, true); return command.Buffered ? results.ToList() : results; } - } finally + } + finally { if (wasClosed) cnn.Close(); } } /// - /// Perform a multi mapping query with arbitrary input parameters + /// Perform a asynchronous multi-mapping query with an arbitrary number of input types. + /// This returns a single type, combined from the raw types via . /// - /// The return type - /// - /// - /// array of types in the recordset - /// - /// - /// - /// - /// The Field we should split and read the second object from (default: id) - /// Number of seconds before command execution timeout + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// Array of types in the recordset. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. /// Is it a stored proc or a batch? - /// + /// An enumerable of . public static Task> QueryAsync(this IDbConnection cnn, string sql, Type[] types, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) { var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None, default(CancellationToken)); - return MultiMapAsync(cnn, command, types, map, splitOn); + return MultiMapAsync(cnn, command, types, map, splitOn); } private static async Task> MultiMapAsync(this IDbConnection cnn, CommandDefinition command, Type[] types, Func map, string splitOn) @@ -725,7 +912,7 @@ private static async Task> MultiMapAsync(this IDbC if (wasClosed) await ((DbConnection)cnn).OpenAsync().ConfigureAwait(false); using (var cmd = (DbCommand)command.SetupCommand(cnn, info.ParamReader)) using (var reader = await ExecuteReaderWithFlagsFallbackAsync(cmd, wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult, command.CancellationToken).ConfigureAwait(false)) { - var results = MultiMapImpl(null, default(CommandDefinition), types, map, splitOn, reader, identity, true); + var results = MultiMapImpl(null, default(CommandDefinition), types, map, splitOn, reader, identity, true); return command.Buffered ? results.ToList() : results; } } @@ -742,29 +929,32 @@ private static IEnumerable ExecuteReaderSync(IDataReader reader, Func - /// Execute a command that returns multiple result sets, and access each in turn + /// Execute a command that returns multiple result sets, and access each in turn. /// - public static Task QueryMultipleAsync( - this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null - ) - { - var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered); - return QueryMultipleAsync(cnn, command); - } + /// The connection to query on. + /// The SQL to execute for this query. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + public static Task QueryMultipleAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryMultipleAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered)); /// - /// Execute a command that returns multiple result sets, and access each in turn + /// Execute a command that returns multiple result sets, and access each in turn. /// + /// The connection to query on. + /// The command to execute for this query. public static async Task QueryMultipleAsync(this IDbConnection cnn, CommandDefinition command) { object param = command.Parameters; - Identity identity = new Identity(command.CommandText, command.CommandType, cnn, typeof(GridReader), param?.GetType(), null); + var identity = new Identity(command.CommandText, command.CommandType, cnn, typeof(GridReader), param?.GetType(), null); CacheInfo info = GetCacheInfo(identity, param, command.AddToCache); DbCommand cmd = null; @@ -790,7 +980,8 @@ public static async Task QueryMultipleAsync(this IDbConnection cnn, if (!reader.IsClosed) { try { cmd.Cancel(); } - catch { /* don't spoil the existing exception */ } + catch { /* don't spoil the existing exception */ + } } reader.Dispose(); } @@ -801,8 +992,14 @@ public static async Task QueryMultipleAsync(this IDbConnection cnn, } /// - /// Execute parameterized SQL and return an + /// Execute parameterized SQL and return an . /// + /// The connection to execute on. + /// The SQL to execute. + /// The parameters to use for this command. + /// The transaction to use for this command. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? /// An that can be used to iterate over the results of the SQL query. /// /// This is typically used when the results of a query are not processed by Dapper, for example, used to fill a @@ -819,26 +1016,21 @@ public static async Task QueryMultipleAsync(this IDbConnection cnn, /// ]]> /// /// - public static Task ExecuteReaderAsync( - this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null - ) - { - var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered); - return ExecuteReaderImplAsync(cnn, command); - } + public static Task ExecuteReaderAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + ExecuteReaderImplAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered)); /// - /// Execute parameterized SQL and return an + /// Execute parameterized SQL and return an . /// + /// The connection to execute on. + /// The command to execute. /// An that can be used to iterate over the results of the SQL query. /// /// This is typically used when the results of a query are not processed by Dapper, for example, used to fill a /// or . /// - public static Task ExecuteReaderAsync(this IDbConnection cnn, CommandDefinition command) - { - return ExecuteReaderImplAsync(cnn, command); - } + public static Task ExecuteReaderAsync(this IDbConnection cnn, CommandDefinition command) => + ExecuteReaderImplAsync(cnn, command); private static async Task ExecuteReaderImplAsync(IDbConnection cnn, CommandDefinition command) { @@ -862,46 +1054,50 @@ private static async Task ExecuteReaderImplAsync(IDbConnection cnn, } /// - /// Execute parameterized SQL that selects a single value + /// Execute parameterized SQL that selects a single value. /// - /// The first cell selected - public static Task ExecuteScalarAsync( - this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null - ) - { - var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered); - return ExecuteScalarImplAsync(cnn, command); - } + /// The connection to execute on. + /// The SQL to execute. + /// The parameters to use for this command. + /// The transaction to use for this command. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// The first cell returned, as . + public static Task ExecuteScalarAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + ExecuteScalarImplAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered)); /// - /// Execute parameterized SQL that selects a single value + /// Execute parameterized SQL that selects a single value. /// - /// The first cell selected - public static Task ExecuteScalarAsync( - this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null - ) - { - var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered); - return ExecuteScalarImplAsync(cnn, command); - } + /// The type to return. + /// The connection to execute on. + /// The SQL to execute. + /// The parameters to use for this command. + /// The transaction to use for this command. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// The first cell returned, as . + public static Task ExecuteScalarAsync(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + ExecuteScalarImplAsync(cnn, new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered)); /// - /// Execute parameterized SQL that selects a single value + /// Execute parameterized SQL that selects a single value. /// - /// The first cell selected - public static Task ExecuteScalarAsync(this IDbConnection cnn, CommandDefinition command) - { - return ExecuteScalarImplAsync(cnn, command); - } + /// The connection to execute on. + /// The command to execute. + /// The first cell selected as . + public static Task ExecuteScalarAsync(this IDbConnection cnn, CommandDefinition command) => + ExecuteScalarImplAsync(cnn, command); /// /// Execute parameterized SQL that selects a single value /// - /// The first cell selected - public static Task ExecuteScalarAsync(this IDbConnection cnn, CommandDefinition command) - { - return ExecuteScalarImplAsync(cnn, command); - } + /// The type to return. + /// The connection to execute on. + /// The command to execute. + /// The first cell selected as . + public static Task ExecuteScalarAsync(this IDbConnection cnn, CommandDefinition command) => + ExecuteScalarImplAsync(cnn, command); private static async Task ExecuteScalarImplAsync(IDbConnection cnn, CommandDefinition command) { diff --git a/Dapper/SqlMapper.cs b/Dapper/SqlMapper.cs index 6d91a42550cf684c876ceb85ccd73183d86580a7..a7128eee572feff1604b52edcc6d99322a1ebab9 100644 --- a/Dapper/SqlMapper.cs +++ b/Dapper/SqlMapper.cs @@ -210,7 +210,7 @@ static SqlMapper() } /// - /// Clear the registered type handlers + /// Clear the registered type handlers. /// public static void ResetTypeHandlers() => ResetTypeHandlers(true); @@ -219,11 +219,11 @@ private static void ResetTypeHandlers(bool clone) typeHandlers = new Dictionary(); #if !COREFX AddTypeHandlerImpl(typeof(DataTable), new DataTableHandler(), clone); - try // see https://github.com/StackExchange/dapper-dot-net/issues/424 + try { AddSqlDataRecordsTypeHandler(clone); } - catch { } + catch { /* https://github.com/StackExchange/dapper-dot-net/issues/424 */ } #endif AddTypeHandlerImpl(typeof(XmlDocument), new XmlDocumentHandler(), clone); AddTypeHandlerImpl(typeof(XDocument), new XDocumentHandler(), clone); @@ -239,8 +239,10 @@ private static void AddSqlDataRecordsTypeHandler(bool clone) #endif /// - /// Configure the specified type to be mapped to a given db-type + /// Configure the specified type to be mapped to a given db-type. /// + /// The type to map from. + /// The database type to map to. public static void AddTypeMap(Type type, DbType dbType) { // use clone, mutate, replace to avoid threading issues @@ -252,8 +254,9 @@ public static void AddTypeMap(Type type, DbType dbType) } /// - /// Removes the specified type from the Type/DbType mapping table + /// Removes the specified type from the Type/DbType mapping table. /// + /// The type to remove from the current map. public static void RemoveTypeMap(Type type) { // use clone, mutate, replace to avoid threading issues @@ -268,24 +271,29 @@ public static void RemoveTypeMap(Type type) } /// - /// Configure the specified type to be processed by a custom handler + /// Configure the specified type to be processed by a custom handler. /// + /// The type to handle. + /// The handler to process the . public static void AddTypeHandler(Type type, ITypeHandler handler) => AddTypeHandlerImpl(type, handler, true); internal static bool HasTypeHandler(Type type) => typeHandlers.ContainsKey(type); /// - /// Configure the specified type to be processed by a custom handler + /// Configure the specified type to be processed by a custom handler. /// + /// The type to handle. + /// The handler to process the . + /// Whether to clone the current type handler map. public static void AddTypeHandlerImpl(Type type, ITypeHandler handler, bool clone) { if (type == null) throw new ArgumentNullException(nameof(type)); Type secondary = null; - if(type.IsValueType()) + if (type.IsValueType()) { var underlying = Nullable.GetUnderlyingType(type); - if(underlying == null) + if (underlying == null) { secondary = typeof(Nullable<>).MakeGenericType(type); // the Nullable // type is already the T @@ -304,7 +312,7 @@ public static void AddTypeHandlerImpl(Type type, ITypeHandler handler, bool clon #pragma warning disable 618 typeof(TypeHandlerCache<>).MakeGenericType(type).GetMethod(nameof(TypeHandlerCache.SetHandler), BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { handler }); - if(secondary != null) + if (secondary != null) { typeof(TypeHandlerCache<>).MakeGenericType(secondary).GetMethod(nameof(TypeHandlerCache.SetHandler), BindingFlags.Static | BindingFlags.NonPublic).Invoke(null, new object[] { handler }); } @@ -323,10 +331,11 @@ public static void AddTypeHandlerImpl(Type type, ITypeHandler handler, bool clon } /// - /// Configure the specified type to be processed by a custom handler + /// Configure the specified type to be processed by a custom handler. /// - public static void AddTypeHandler(TypeHandler handler) => - AddTypeHandlerImpl(typeof(T), handler, true); + /// The type to handle. + /// The handler for the type . + public static void AddTypeHandler(TypeHandler handler) => AddTypeHandlerImpl(typeof(T), handler, true); private static Dictionary typeHandlers; @@ -335,8 +344,9 @@ public static void AddTypeHandlerImpl(Type type, ITypeHandler handler, bool clon private const string ObsoleteInternalUsageOnly = "This method is for internal use only"; /// - /// Get the DbType that maps to a given value + /// Get the DbType that maps to a given value. /// + /// The object to get a corresponding database type for. [Obsolete(ObsoleteInternalUsageOnly, false)] #if !COREFX [Browsable(false)] @@ -352,6 +362,10 @@ public static DbType GetDbType(object value) /// /// OBSOLETE: For internal usage only. Lookup the DbType and handler for a given Type and member /// + /// The type to lookup. + /// The name (for error messages). + /// Whether to demand a value (throw if missing). + /// The handler for . [Obsolete(ObsoleteInternalUsageOnly, false)] #if !COREFX [Browsable(false)] @@ -406,61 +420,84 @@ public static DbType LookupDbType(Type type, string name, bool demand, out IType /// Obtains the data as a list; if it is *already* a list, the original object is returned without /// any duplication; otherwise, ToList() is invoked. /// + /// The type of element in the list. + /// The enumerable to return as a list. public static List AsList(this IEnumerable source) => (source == null || source is List) ? (List)source : source.ToList(); /// - /// Execute parameterized SQL + /// Execute parameterized SQL. /// - /// Number of rows affected - public static int Execute( - this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null - ) + /// The connection to query on. + /// The SQL to execute for this query. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// The number of rows affected. + public static int Execute(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered); return ExecuteImpl(cnn, ref command); } + /// - /// Execute parameterized SQL + /// Execute parameterized SQL. /// - /// Number of rows affected + /// The connection to execute on. + /// The command to execute on this connection. + /// The number of rows affected. public static int Execute(this IDbConnection cnn, CommandDefinition command) => ExecuteImpl(cnn, ref command); /// - /// Execute parameterized SQL that selects a single value + /// Execute parameterized SQL that selects a single value. /// - /// The first cell selected - public static object ExecuteScalar( - this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null - ) + /// The connection to execute on. + /// The SQL to execute. + /// The parameters to use for this command. + /// The transaction to use for this command. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// The first cell selected as . + public static object ExecuteScalar(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered); return ExecuteScalarImpl(cnn, ref command); } /// - /// Execute parameterized SQL that selects a single value + /// Execute parameterized SQL that selects a single value. /// - /// The first cell selected - public static T ExecuteScalar( - this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null - ) + /// The type to return. + /// The connection to execute on. + /// The SQL to execute. + /// The parameters to use for this command. + /// The transaction to use for this command. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// The first cell returned, as . + public static T ExecuteScalar(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered); return ExecuteScalarImpl(cnn, ref command); } /// - /// Execute parameterized SQL that selects a single value + /// Execute parameterized SQL that selects a single value. /// - /// The first cell selected + /// The connection to execute on. + /// The command to execute. + /// The first cell selected as . public static object ExecuteScalar(this IDbConnection cnn, CommandDefinition command) => ExecuteScalarImpl(cnn, ref command); /// - /// Execute parameterized SQL that selects a single value + /// Execute parameterized SQL that selects a single value. /// - /// The first cell selected + /// The type to return. + /// The connection to execute on. + /// The command to execute. + /// The first cell selected as . public static T ExecuteScalar(this IDbConnection cnn, CommandDefinition command) => ExecuteScalarImpl(cnn, ref command); @@ -533,8 +570,14 @@ private static int ExecuteImpl(this IDbConnection cnn, ref CommandDefinition com } /// - /// Execute parameterized SQL and return an + /// Execute parameterized SQL and return an . /// + /// The connection to execute on. + /// The SQL to execute. + /// The parameters to use for this command. + /// The transaction to use for this command. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? /// An that can be used to iterate over the results of the SQL query. /// /// This is typically used when the results of a query are not processed by Dapper, for example, used to fill a @@ -551,9 +594,7 @@ private static int ExecuteImpl(this IDbConnection cnn, ref CommandDefinition com /// ]]> /// /// - public static IDataReader ExecuteReader( - this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null -) + public static IDataReader ExecuteReader(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered); var reader = ExecuteReaderImpl(cnn, ref command, CommandBehavior.Default, out IDbCommand dbcmd); @@ -561,8 +602,10 @@ private static int ExecuteImpl(this IDbConnection cnn, ref CommandDefinition com } /// - /// Execute parameterized SQL and return an + /// Execute parameterized SQL and return an . /// + /// The connection to execute on. + /// The command to execute. /// An that can be used to iterate over the results of the SQL query. /// /// This is typically used when the results of a query are not processed by Dapper, for example, used to fill a @@ -573,9 +616,13 @@ public static IDataReader ExecuteReader(this IDbConnection cnn, CommandDefinitio var reader = ExecuteReaderImpl(cnn, ref command, CommandBehavior.Default, out IDbCommand dbcmd); return new WrappedReader(dbcmd, reader); } + /// - /// Execute parameterized SQL and return an + /// Execute parameterized SQL and return an . /// + /// The connection to execute on. + /// The command to execute. + /// The flags for this reader. /// An that can be used to iterate over the results of the SQL query. /// /// This is typically used when the results of a query are not processed by Dapper, for example, used to fill a @@ -588,59 +635,87 @@ public static IDataReader ExecuteReader(this IDbConnection cnn, CommandDefinitio } /// - /// Return a sequence of dynamic objects with properties matching the columns + /// Return a sequence of dynamic objects with properties matching the columns. /// + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// Whether to buffer the results in memory. + /// The command timeout (in seconds). + /// The type of command to execute. /// Note: each row can be accessed via "dynamic", or by casting to an IDictionary<string,object> - public static IEnumerable Query(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) - { - return Query(cnn, sql, param as object, transaction, buffered, commandTimeout, commandType); - } + public static IEnumerable Query(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) => + Query(cnn, sql, param as object, transaction, buffered, commandTimeout, commandType); /// - /// Return a dynamic object with properties matching the columns + /// Return a dynamic object with properties matching the columns. /// + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> - public static dynamic QueryFirst(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) - { - return QueryFirst(cnn, sql, param as object, transaction, commandTimeout, commandType); - } + public static dynamic QueryFirst(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryFirst(cnn, sql, param as object, transaction, commandTimeout, commandType); /// - /// Return a dynamic object with properties matching the columns + /// Return a dynamic object with properties matching the columns. /// + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> - public static dynamic QueryFirstOrDefault(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) - { - return QueryFirstOrDefault(cnn, sql, param as object, transaction, commandTimeout, commandType); - } + public static dynamic QueryFirstOrDefault(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QueryFirstOrDefault(cnn, sql, param as object, transaction, commandTimeout, commandType); /// - /// Return a dynamic object with properties matching the columns + /// Return a dynamic object with properties matching the columns. /// + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> - public static dynamic QuerySingle(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) - { - return QuerySingle(cnn, sql, param as object, transaction, commandTimeout, commandType); - } + public static dynamic QuerySingle(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QuerySingle(cnn, sql, param as object, transaction, commandTimeout, commandType); /// - /// Return a dynamic object with properties matching the columns + /// Return a dynamic object with properties matching the columns. /// + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. /// Note: the row can be accessed via "dynamic", or by casting to an IDictionary<string,object> - public static dynamic QuerySingleOrDefault(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) - { - return QuerySingleOrDefault(cnn, sql, param as object, transaction, commandTimeout, commandType); - } - - /// - /// Executes a query, returning the data typed as per T - /// - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + public static dynamic QuerySingleOrDefault(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) => + QuerySingleOrDefault(cnn, sql, param as object, transaction, commandTimeout, commandType); + + /// + /// Executes a query, returning the data typed as . + /// + /// The type of results to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// Whether to buffer results in memory. + /// The command timeout (in seconds). + /// The type of command to execute. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// - public static IEnumerable Query( - this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null - ) + public static IEnumerable Query(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) { var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None); var data = QueryImpl(cnn, command, typeof(T)); @@ -648,69 +723,102 @@ public static dynamic QuerySingleOrDefault(this IDbConnection cnn, string sql, o } /// - /// Executes a single-row query, returning the data typed as per T + /// Executes a single-row query, returning the data typed as . /// - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// The type of result to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// - public static T QueryFirst( - this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null - ) + public static T QueryFirst(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None); return QueryRowImpl(cnn, Row.First, ref command, typeof(T)); } /// - /// Executes a single-row query, returning the data typed as per T + /// Executes a single-row query, returning the data typed as . /// - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// The type of result to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// - public static T QueryFirstOrDefault( - this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null - ) + public static T QueryFirstOrDefault(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None); return QueryRowImpl(cnn, Row.FirstOrDefault, ref command, typeof(T)); } /// - /// Executes a single-row query, returning the data typed as per T + /// Executes a single-row query, returning the data typed as . /// - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// The type of result to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// - public static T QuerySingle( - this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null - ) + public static T QuerySingle(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None); return QueryRowImpl(cnn, Row.Single, ref command, typeof(T)); } + /// - /// Executes a single-row query, returning the data typed as per T + /// Executes a single-row query, returning the data typed as . /// - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// The type of result to return. + /// The connection to query on. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// - public static T QuerySingleOrDefault( - this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null - ) + public static T QuerySingleOrDefault(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None); return QueryRowImpl(cnn, Row.SingleOrDefault, ref command, typeof(T)); } /// - /// Executes a single-row query, returning the data typed as per the Type suggested + /// Executes a single-row query, returning the data typed as . /// - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// Whether to buffer results in memory. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// - public static IEnumerable Query( - this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null - ) + public static IEnumerable Query(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, bool buffered = true, int? commandTimeout = null, CommandType? commandType = null) { if (type == null) throw new ArgumentNullException(nameof(type)); var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None); @@ -719,14 +827,21 @@ public static dynamic QuerySingleOrDefault(this IDbConnection cnn, string sql, o } /// - /// Executes a single-row query, returning the data typed as per the Type suggested + /// Executes a single-row query, returning the data typed as . /// - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// - public static object QueryFirst( - this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null - ) + public static object QueryFirst(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { if (type == null) throw new ArgumentNullException(nameof(type)); var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None); @@ -734,14 +849,21 @@ public static dynamic QuerySingleOrDefault(this IDbConnection cnn, string sql, o } /// - /// Executes a single-row query, returning the data typed as per the Type suggested + /// Executes a single-row query, returning the data typed as . /// - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// - public static object QueryFirstOrDefault( - this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null - ) + public static object QueryFirstOrDefault(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { if (type == null) throw new ArgumentNullException(nameof(type)); var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None); @@ -749,14 +871,21 @@ public static dynamic QuerySingleOrDefault(this IDbConnection cnn, string sql, o } /// - /// Executes a single-row query, returning the data typed as per the Type suggested + /// Executes a single-row query, returning the data typed as . /// - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// - public static object QuerySingle( - this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null - ) + public static object QuerySingle(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { if (type == null) throw new ArgumentNullException(nameof(type)); var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None); @@ -764,14 +893,21 @@ public static dynamic QuerySingleOrDefault(this IDbConnection cnn, string sql, o } /// - /// Executes a single-row query, returning the data typed as per the Type suggested + /// Executes a single-row query, returning the data typed as . /// - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// The connection to query on. + /// The type to return. + /// The SQL to execute for the query. + /// The parameters to pass, if any. + /// The transaction to use, if any. + /// The command timeout (in seconds). + /// The type of command to execute. + /// is null. + /// + /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// - public static object QuerySingleOrDefault( - this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null - ) + public static object QuerySingleOrDefault(this IDbConnection cnn, Type type, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { if (type == null) throw new ArgumentNullException(nameof(type)); var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.None); @@ -779,10 +915,13 @@ public static dynamic QuerySingleOrDefault(this IDbConnection cnn, string sql, o } /// - /// Executes a query, returning the data typed as per T + /// Executes a query, returning the data typed as . /// - /// the dynamic param may seem a bit odd, but this works around a major usability issue in vs, if it is Object vs completion gets annoying. Eg type new [space] get new object - /// A sequence of data of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// The type of results to return. + /// The connection to query on. + /// The command used to query on this connection. + /// + /// A sequence of data of ; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// public static IEnumerable Query(this IDbConnection cnn, CommandDefinition command) @@ -792,67 +931,77 @@ public static IEnumerable Query(this IDbConnection cnn, CommandDefinition } /// - /// Executes a query, returning the data typed as per T + /// Executes a query, returning the data typed as . /// - /// the dynamic param may seem a bit odd, but this works around a major usability issue in vs, if it is Object vs completion gets annoying. Eg type new [space] get new object - /// A single instance or null of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// The type of results to return. + /// The connection to query on. + /// The command used to query on this connection. + /// + /// A single instance or null of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// - public static T QueryFirst(this IDbConnection cnn, CommandDefinition command) - { - return QueryRowImpl(cnn, Row.First, ref command, typeof(T)); - } + public static T QueryFirst(this IDbConnection cnn, CommandDefinition command) => + QueryRowImpl(cnn, Row.First, ref command, typeof(T)); /// - /// Executes a query, returning the data typed as per T + /// Executes a query, returning the data typed as . /// - /// the dynamic param may seem a bit odd, but this works around a major usability issue in vs, if it is Object vs completion gets annoying. Eg type new [space] get new object - /// A single or null instance of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// The type of results to return. + /// The connection to query on. + /// The command used to query on this connection. + /// + /// A single or null instance of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// - public static T QueryFirstOrDefault(this IDbConnection cnn, CommandDefinition command) - { - return QueryRowImpl(cnn, Row.FirstOrDefault, ref command, typeof(T)); - } + public static T QueryFirstOrDefault(this IDbConnection cnn, CommandDefinition command) => + QueryRowImpl(cnn, Row.FirstOrDefault, ref command, typeof(T)); /// - /// Executes a query, returning the data typed as per T + /// Executes a query, returning the data typed as . /// - /// the dynamic param may seem a bit odd, but this works around a major usability issue in vs, if it is Object vs completion gets annoying. Eg type new [space] get new object - /// A single instance of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// The type of results to return. + /// The connection to query on. + /// The command used to query on this connection. + /// + /// A single instance of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// - public static T QuerySingle(this IDbConnection cnn, CommandDefinition command) - { - return QueryRowImpl(cnn, Row.Single, ref command, typeof(T)); - } + public static T QuerySingle(this IDbConnection cnn, CommandDefinition command) => + QueryRowImpl(cnn, Row.Single, ref command, typeof(T)); /// - /// Executes a query, returning the data typed as per T + /// Executes a query, returning the data typed as . /// - /// the dynamic param may seem a bit odd, but this works around a major usability issue in vs, if it is Object vs completion gets annoying. Eg type new [space] get new object - /// A single instance of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is + /// The type of results to return. + /// The connection to query on. + /// The command used to query on this connection. + /// + /// A single instance of the supplied type; if a basic type (int, string, etc) is queried then the data from the first column in assumed, otherwise an instance is /// created per row, and a direct column-name===member-name mapping is assumed (case insensitive). /// - public static T QuerySingleOrDefault(this IDbConnection cnn, CommandDefinition command) - { - return QueryRowImpl(cnn, Row.SingleOrDefault, ref command, typeof(T)); - } + public static T QuerySingleOrDefault(this IDbConnection cnn, CommandDefinition command) => + QueryRowImpl(cnn, Row.SingleOrDefault, ref command, typeof(T)); /// - /// Execute a command that returns multiple result sets, and access each in turn + /// Execute a command that returns multiple result sets, and access each in turn. /// - public static GridReader QueryMultiple( - this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null - ) + /// The connection to query on. + /// The SQL to execute for this query. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + public static GridReader QueryMultiple(this IDbConnection cnn, string sql, object param = null, IDbTransaction transaction = null, int? commandTimeout = null, CommandType? commandType = null) { var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, CommandFlags.Buffered); return QueryMultipleImpl(cnn, ref command); } /// - /// Execute a command that returns multiple result sets, and access each in turn + /// Execute a command that returns multiple result sets, and access each in turn. /// + /// The connection to query on. + /// The command to execute for this query. public static GridReader QueryMultiple(this IDbConnection cnn, CommandDefinition command) => QueryMultipleImpl(cnn, ref command); @@ -954,7 +1103,7 @@ private static IEnumerable QueryImpl(this IDbConnection cnn, CommandDefini yield return (T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture); } } - while (reader.NextResult()) { } + while (reader.NextResult()) { /* ignore subsequent result sets */ } // happy path; close the reader cleanly - no // need for "Cancel" etc reader.Dispose(); @@ -982,7 +1131,7 @@ private static IEnumerable QueryImpl(this IDbConnection cnn, CommandDefini internal enum Row { First = 0, - FirstOrDefault = 1, // &FirstOrDefault != 0: allow zero rows + FirstOrDefault = 1, // & FirstOrDefault != 0: allow zero rows Single = 2, // & Single != 0: demand at least one row SingleOrDefault = 3 } @@ -1054,13 +1203,13 @@ private static T QueryRowImpl(IDbConnection cnn, Row row, ref CommandDefiniti result = (T)Convert.ChangeType(val, convertToType, CultureInfo.InvariantCulture); } if ((row & Row.Single) != 0 && reader.Read()) ThrowMultipleRows(row); - while (reader.Read()) { } + while (reader.Read()) { /* ignore subsequent rows */ } } else if ((row & Row.FirstOrDefault) == 0) // demanding a row, and don't have one { ThrowZeroRows(row); } - while (reader.NextResult()) { } + while (reader.NextResult()) { /* ignore subsequent result sets */ } // happy path; close the reader cleanly - no // need for "Cancel" etc reader.Dispose(); @@ -1086,175 +1235,160 @@ private static T QueryRowImpl(IDbConnection cnn, Row row, ref CommandDefiniti } /// - /// Maps a query to objects + /// Perform a multi-mapping query with 2 input types. + /// This returns a single type, combined from the raw types via . /// - /// The first type in the record set - /// The second type in the record set - /// The return type - /// - /// - /// - /// - /// - /// - /// The Field we should split and read the second object from (default: id) - /// Number of seconds before command execution timeout + /// The first type in the recordset. + /// The second type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. /// Is it a stored proc or a batch? - /// - public static IEnumerable Query( - this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null - ) - { - return MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); - } - - /// - /// Maps a query to objects - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// The Field we should split and read the second object from (default: id) - /// Number of seconds before command execution timeout - /// - /// - public static IEnumerable Query( - this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null - ) - { - return MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); - } - - /// - /// Perform a multi mapping query with 4 input parameters - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static IEnumerable Query( - this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null - ) - { - return MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); - } - - /// - /// Perform a multi mapping query with 5 input parameters - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static IEnumerable Query( - this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null -) - { - return MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); - } - - /// - /// Perform a multi mapping query with 6 input parameters - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static IEnumerable Query( - this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null -) - { - return MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); - } - - /// - /// Perform a multi mapping query with 7 input parameters - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - /// - public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) - { - return MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); - } - - /// - /// Perform a multi mapping query with arbitrary input parameters - /// - /// The return type - /// - /// - /// array of types in the record set - /// - /// - /// - /// - /// The Field we should split and read the second object from (default: id) - /// Number of seconds before command execution timeout + /// An enumerable of . + public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); + + /// + /// Perform a multi-mapping query with 3 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. /// Is it a stored proc or a batch? - /// + /// An enumerable of . + public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); + + /// + /// Perform a multi-mapping query with 4 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); + + /// + /// Perform a multi-mapping query with 5 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); + + /// + /// Perform a multi-mapping query with 6 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The sixth type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); + + /// + /// Perform a multi-mapping query with 7 input types. + /// This returns a single type, combined from the raw types via . + /// + /// The first type in the recordset. + /// The second type in the recordset. + /// The third type in the recordset. + /// The fourth type in the recordset. + /// The fifth type in the recordset. + /// The sixth type in the recordset. + /// The seventh type in the recordset. + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . + public static IEnumerable Query(this IDbConnection cnn, string sql, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) => + MultiMap(cnn, sql, map, param, transaction, buffered, splitOn, commandTimeout, commandType); + + /// + /// Perform a multi-mapping query with an arbitrary number of input types. + /// This returns a single type, combined from the raw types via . + /// + /// The combined type to return. + /// The connection to query on. + /// The SQL to execute for this query. + /// Array of types in the recordset. + /// The function to map row types to the return type. + /// The parameters to use for this query. + /// The transaction to use for this query. + /// Whether to buffer the results in memory. + /// The field we should split and read the second object from (default: "Id"). + /// Number of seconds before command execution timeout. + /// Is it a stored proc or a batch? + /// An enumerable of . public static IEnumerable Query(this IDbConnection cnn, string sql, Type[] types, Func map, object param = null, IDbTransaction transaction = null, bool buffered = true, string splitOn = "Id", int? commandTimeout = null, CommandType? commandType = null) { var command = new CommandDefinition(sql, param, transaction, commandTimeout, commandType, buffered ? CommandFlags.Buffered : CommandFlags.None); - var results = MultiMapImpl(cnn, command, types, map, splitOn, null, null, true); + var results = MultiMapImpl(cnn, command, types, map, splitOn, null, null, true); return buffered ? results.ToList() : results; } @@ -1285,7 +1419,7 @@ public static IEnumerable Query(this IDbConnection cnn, string ownedReader = ExecuteReaderWithFlagsFallback(ownedCommand, wasClosed, CommandBehavior.SequentialAccess | CommandBehavior.SingleResult); reader = ownedReader; } - DeserializerState deserializer = default(DeserializerState); + var deserializer = default(DeserializerState); Func[] otherDeserializers; int hash = GetColumnHash(reader); @@ -1305,9 +1439,9 @@ public static IEnumerable Query(this IDbConnection cnn, string { yield return mapIt(reader); } - if(finalize) + if (finalize) { - while (reader.NextResult()) { } + while (reader.NextResult()) { /* ignore remaining result sets */ } command.OnCompleted(); } } @@ -1377,7 +1511,7 @@ private static IEnumerable MultiMapImpl(this IDbConnection cnn } if (finalize) { - while (reader.NextResult()) { } + while (reader.NextResult()) { /* ignore subsequent result sets */ } command.OnCompleted(); } } @@ -1438,7 +1572,7 @@ private static IEnumerable MultiMapImpl(this IDbConnection cnn var deserializers = new List>(); var splits = splitOn.Split(',').Select(s => s.Trim()).ToArray(); bool isMultiSplit = splits.Length > 1; - if (types.First() == typeof(object)) + if (types[0] == typeof(object)) { // we go left to right for dynamic multi-mapping so that the madness of TestMultiMappingVariations // is supported @@ -1632,8 +1766,7 @@ private static void PassByPosition(IDbCommand cmd) private static Func GetDeserializer(Type type, IDataReader reader, int startBound, int length, bool returnNullIfFirstMissing) { // dynamic is passed in as Object ... by c# design - if (type == typeof(object) - || type == typeof(DapperRow)) + if (type == typeof(object) || type == typeof(DapperRow)) { return GetDapperRowDeserializer(reader, startBound, length, returnNullIfFirstMissing); } @@ -1658,9 +1791,8 @@ private static void PassByPosition(IDbCommand cmd) private static Exception MultiMapException(IDataRecord reader) { bool hasFields = false; - try { - hasFields = reader != null && reader.FieldCount != 0; - } catch { } + try { hasFields = reader != null && reader.FieldCount != 0; } + catch { /* don't throw when trying to throw */ } if (hasFields) return new ArgumentException("When using the multi-mapping APIs ensure you set the splitOn param if you have keys other than Id", "splitOn"); else @@ -1729,10 +1861,9 @@ private static Exception MultiMapException(IDataRecord reader) }; } /// - /// Internal use only + /// Internal use only. /// - /// - /// + /// The object to convert to a character. #if !COREFX [Browsable(false)] #endif @@ -1741,14 +1872,15 @@ private static Exception MultiMapException(IDataRecord reader) public static char ReadChar(object value) { if (value == null || value is DBNull) throw new ArgumentNullException(nameof(value)); - string s = value as string; + var s = value as string; if (s == null || s.Length != 1) throw new ArgumentException("A single-character was expected", nameof(value)); return s[0]; } /// - /// Internal use only + /// Internal use only. /// + /// The object to convert to a character. #if !COREFX [Browsable(false)] #endif @@ -1757,14 +1889,17 @@ public static char ReadChar(object value) public static char? ReadNullableChar(object value) { if (value == null || value is DBNull) return null; - string s = value as string; + var s = value as string; if (s == null || s.Length != 1) throw new ArgumentException("A single-character was expected", nameof(value)); return s[0]; } /// - /// Internal use only + /// Internal use only. /// + /// The parameter collection to search in. + /// The command for this fetch. + /// The name of the parameter to get. #if !COREFX [Browsable(false)] #endif @@ -1816,9 +1951,13 @@ internal static int GetListPaddingExtraCount(int count) private static string GetInListRegex(string name, bool byPosition) => byPosition ? (@"(\?)" + Regex.Escape(name) + @"\?(?!\w)(\s+(?i)unknown(?-i))?") : (@"([?@:]" + Regex.Escape(name) + @")(?!\w)(\s+(?i)unknown(?-i))?"); + /// - /// Internal use only + /// Internal use only. /// + /// The command to pack parameters for. + /// The name prefix for these parameters. + /// The parameter value can be an #if !COREFX [Browsable(false)] #endif @@ -2049,6 +2188,7 @@ private static bool TryStringSplit(ref IEnumerable list, int splitAt, string nam /// /// OBSOLETE: For internal usage only. Sanitizes the paramter value with proper type casting. /// + /// The value to sanitize. [Obsolete(ObsoleteInternalUsageOnly, false)] public static object SanitizeParameterValue(object value) { @@ -2090,8 +2230,10 @@ private static IEnumerable FilterParameters(IEnumerable - /// Replace all literal tokens with their text form + /// Replace all literal tokens with their text form. /// + /// The parameter lookup to do replacements with. + /// The command to repalce parameters in. public static void ReplaceLiterals(this IParameterLookup parameters, IDbCommand command) { var tokens = GetLiteralTokens(command.CommandText); @@ -2101,8 +2243,9 @@ public static void ReplaceLiterals(this IParameterLookup parameters, IDbCommand internal static readonly MethodInfo format = typeof(SqlMapper).GetMethod("Format", BindingFlags.Public | BindingFlags.Static); /// - /// Convert numeric values to their string form for SQL literal purposes + /// Convert numeric values to their string form for SQL literal purposes. /// + /// The value to get a string for. [Obsolete(ObsoleteInternalUsageOnly)] public static string Format(object value) { @@ -2209,12 +2352,13 @@ internal static IList GetLiteralTokens(string sql) } /// - /// Internal use only + /// Internal use only. /// - public static Action CreateParamInfoGenerator(Identity identity, bool checkForDuplicates, bool removeUnused) - { - return CreateParamInfoGenerator(identity, checkForDuplicates, removeUnused, GetLiteralTokens(identity.sql)); - } + /// The identity of the generator. + /// Whether to check for duplicates. + /// Whether to remove unused parameters. + public static Action CreateParamInfoGenerator(Identity identity, bool checkForDuplicates, bool removeUnused) => + CreateParamInfoGenerator(identity, checkForDuplicates, removeUnused, GetLiteralTokens(identity.sql)); private static bool IsValueTuple(Type type) => type?.IsValueType() == true && type.FullName.StartsWith("System.ValueTuple`"); @@ -2813,11 +2957,12 @@ private static readonly MethodInfo /// Gets type-map for the given type /// /// Type map instance, default is to create new instance of DefaultTypeMap - public static Func TypeMapProvider = ( Type type ) => new DefaultTypeMap( type ); + public static Func TypeMapProvider = (Type type) => new DefaultTypeMap(type); /// - /// Gets type-map for the given type + /// Gets type-map for the given . /// + /// The type to get a map for. /// Type map implementation, DefaultTypeMap instance if no override present public static ITypeMap GetTypeMap(Type type) { @@ -3401,6 +3546,10 @@ private static void LoadLocalAddress(ILGenerator il, int index) /// /// Throws a data exception, only used internally /// + /// The exception to throw. + /// The index the exception occured at. + /// The reader the exception occured in. + /// The value that caused the exception. [Obsolete(ObsoleteInternalUsageOnly, false)] public static void ThrowDataException(Exception ex, int index, IDataReader reader, object value) { @@ -3479,21 +3628,23 @@ public static IEqualityComparer ConnectionStringComparer #if !COREFX /// - /// Key used to indicate the type name associated with a DataTable + /// Key used to indicate the type name associated with a DataTable. /// private const string DataTableTypeNameKey = "dapper:TypeName"; /// - /// Used to pass a DataTable as a TableValuedParameter + /// Used to pass a DataTable as a . /// - public static ICustomQueryParameter AsTableValuedParameter(this DataTable table, string typeName = null) - { - return new TableValuedParameter(table, typeName); - } + /// The to create this parameter for. + /// The name of the type this parameter is for. + public static ICustomQueryParameter AsTableValuedParameter(this DataTable table, string typeName = null) => + new TableValuedParameter(table, typeName); /// - /// Associate a DataTable with a type name + /// Associate a DataTable with a type name. /// + /// The that does with the . + /// The name of the type this table is for. public static void SetTypeName(this DataTable table, string typeName) { if (table != null) @@ -3506,21 +3657,19 @@ public static void SetTypeName(this DataTable table, string typeName) } /// - /// Fetch the type name associated with a DataTable + /// Fetch the type name associated with a . /// - public static string GetTypeName(this DataTable table) - { - return table?.ExtendedProperties[DataTableTypeNameKey] as string; - } + /// The that has a type name associated with it. + public static string GetTypeName(this DataTable table) => + table?.ExtendedProperties[DataTableTypeNameKey] as string; /// - /// Used to pass a IEnumerable<SqlDataRecord> as a TableValuedParameter + /// Used to pass a IEnumerable<SqlDataRecord> as a . /// - public static ICustomQueryParameter AsTableValuedParameter(this IEnumerable list, string typeName = null) - { - return new SqlDataRecordListTVPParameter(list, typeName); - } - + /// Thhe list of records to convert to TVPs. + /// The sql parameter type name. + public static ICustomQueryParameter AsTableValuedParameter(this IEnumerable list, string typeName = null) => + new SqlDataRecordListTVPParameter(list, typeName); #endif // one per thread