using System;
using System.Data;
using System.Data.SqlClient;
using System.Xml;
namespace Neo.Afx.ComponentModel
{
///
/// Groups some SQL Server utility methods.
///
public static class SqlUtilities
{
#region Fetch DataTable
///
/// Executes the given Transact-SQL statement or stored procedure
/// with the given (optional) parameters and returns a DataTable
/// for the result set returned by the query.
///
/// The sql connection string.
/// The Transact-SQL statement or
/// stored procedure to execute.
///
/// A value indicating how the commandText
/// value is to be interpreted.
///
/// The array of SqlParameters
/// to be queried.
/// If null or zero-length then no parameters are added.
///
/// The result of the command in a DataTable.
public static DataTable FetchDataTable(string connectionString, string commandText, CommandType commandType, params SqlParameter[] parameters)
{
return FetchDataTable(CreateCommand(connectionString, commandText, commandType, parameters));
}
///
/// Executes the given SqlCommand and returns a
/// DataTable for the result set returned by the
/// SqlCommand.
///
/// This method closes and disposes the
/// SqlConnection and disposes the SqlCommand
/// when finished.
///
///
/// The result of the command in a DataTable.
public static DataTable FetchDataTable(this SqlCommand command)
{
return ExecuteReader(command, (CommandBehavior.SchemaOnly & CommandBehavior.KeyInfo),
delegate(SqlDataReader reader)
{
var table = new DataTable();
table.Load(reader, LoadOption.OverwriteChanges);
return table;
});
}
#endregion
#region Create Command
///
/// Creates a SqlCommand object with a new SqlConnection
/// using the given connection string.
///
/// The sql connection string.
/// The Transact-SQL statement or
/// stored procedure to execute.
///
/// A value indicating how the commandText
/// value is to be interpreted.
///
/// The parameters of the Transact-SQL statement
/// or stored procedure. If null or zero-length then no parameters
/// are added.
///
/// A new SqlCommand object.
public static SqlCommand CreateCommand(string connectionString, string commandText, CommandType commandType, params SqlParameter[] parameters)
{
var cmd = new SqlCommand
{
Connection = new SqlConnection(connectionString),
CommandText = commandText,
CommandType = commandType
};
if(parameters != null && parameters.Length > 0)
{
cmd.Parameters.AddRange(parameters);
}
return cmd;
}
#endregion
#region Execute Command
///
/// Executes the given command.
///
/// This method closes and disposes the
/// SqlConnection and disposes the SqlCommand
/// when finished.
///
///
/// The SqlCommand to be executed;
/// must have a valid connection.
///
/// The handler to be invoked.
/// The result of invoking the
/// The type of result returned.
/// If handler is null.
public static T ExecuteCommand(this SqlCommand command, CommandHandler handler)
{
if(handler != null)
{
T result;
using(command)
{
using(command.Connection)
{
command.Connection.Open();
result = handler(command);
} //"using" will close the connection even in case of exception.
}
return result;
}
throw new ArgumentNullException("handler");
}
#endregion
#region ExecuteNonQuery Method
///
/// Executes the given Transact-SQL statement or stored procedure with
/// the given (optional) parameters and returns the number of rows affected.
///
/// The sql connection string.
/// The Transact-SQL statement or
/// stored procedure to execute.
///
/// A value indicating how the commandText
/// value is to be interpreted.
///
/// The array of SqlParameters
/// to be queried.
/// If null or zero-length then no parameters are added.
///
/// The number of rows affected.
public static int ExecuteNonQuery(string connectionString, string commandText, CommandType commandType, params SqlParameter[] parameters)
{
return ExecuteNonQuery(CreateCommand(connectionString, commandText, commandType, parameters));
}
///
/// Executes the given SqlCommand and returns the number
/// of rows affected.
///
/// This method closes and disposes the
/// SqlConnection and disposes the SqlCommand
/// when finished.
///
///
/// The SqlCommand to be executed.
///
/// The number of rows affected.
public static int ExecuteNonQuery(this SqlCommand command)
{
return ExecuteCommand(command, cmd => cmd.ExecuteNonQuery());
}
#endregion
#region ExecuteScalar Method
///
/// Executes the given Transact-SQL statement or stored procedure
/// with the given (optional) parameters and returns the first column
/// of the first row in the result set returned by the query.
/// All other columns and rows are ignored.
///
/// The sql connection string.
/// The Transact-SQL statement or
/// stored procedure to execute.
///
/// A value indicating how the commandText
/// value is to be interpreted.
///
/// The array of SqlParameters
/// to be queried.
/// If null or zero-length then no parameters are added.
///
/// The result of the Transact-SQL statement.
/// The type of the result returned.
public static T ExecuteScalar(string connectionString, string commandText, CommandType commandType, params SqlParameter[] parameters)
{
return ExecuteScalar(CreateCommand(connectionString, commandText, commandType, parameters));
}
///
/// Executes the given SqlCommand and returns the first
/// column of the first row in the result set returned by the query.
/// All other columns and rows are ignored.
///
/// This method closes and disposes the
/// SqlConnection and disposes the SqlCommand
/// when finished.
///
///
/// The SqlCommand to be executed.
///
/// The result of the Transact-SQL statement.
/// The type of the result returned.
public static T ExecuteScalar(this SqlCommand command)
{
return ExecuteCommand(command,
delegate(SqlCommand cmd)
{
var scalar = cmd.ExecuteScalar();
if(scalar.IsNull())
{
return default(T);
}
return (T)scalar;
});
}
#endregion
#region ExecuteReader Method
///
/// Invokes readerHandler with the SqlDataReader
/// created for the given Transact-SQL statement or stored procedure
/// with the given (optional) parameters.
///
/// The sql connection string.
/// The Transact-SQL statement or
/// stored procedure to execute.
///
/// A value indicating how the commandText
/// value is to be interpreted.
///
/// One of the CommandBehavior
/// values.
///
/// A method for consuming the generated reader.
///
/// The array of SqlParameters
/// to be queried.
/// If null or zero-length then no parameters are added.
///
/// The result of the Transact-SQL statement.
/// The type of the result returned.
/// If handler is null.
public static T ExecuteReader(string connectionString, string commandText, CommandType commandType, CommandBehavior commandBehavior, DataReaderHandler handler, params SqlParameter[] parameters)
{
return ExecuteReader(CreateCommand(connectionString, commandText, commandType, parameters), commandBehavior, handler);
}
///
/// Invokes readerHandler with the SqlDataReader
/// created for the given SqlCommand.
///
/// This method closes and disposes the
/// SqlConnection and disposes the SqlCommand
/// after the readerHandler returns.
///
///
/// The SqlCommand to be executed.
///
/// One of the CommandBehavior values.
///
/// A method for consuming the generated reader.
///
/// The results of executing readerHandler.
/// The type of the result to be returned.
/// If handler is null.
public static T ExecuteReader(this SqlCommand command, CommandBehavior commandBehavior, DataReaderHandler handler)
{
if(handler != null)
{
return ExecuteCommand(command,
delegate(SqlCommand cmd)
{
using(var reader = cmd.ExecuteReader(commandBehavior))
{
return handler(reader);
}
});
}
throw new ArgumentNullException("handler");
}
///
/// Crerates a SqlDataReader for the given Transact-SQL statement
/// or stored procedure with the given (optional) parameters.
///
/// The sql connection string.
/// The Transact-SQL statement or
/// stored procedure to execute.
/// A value indicating how the commandText
/// value is to be interpreted.
/// One of the CommandBehavior
/// values.
/// The array of SqlParameters
/// to be queried.
/// If null or zero-length then no parameters are added.
///
/// The result of the Transact-SQL statement.
///
public static SqlDataReader ExecuteReader(string connectionString, string commandText, CommandType commandType, CommandBehavior commandBehavior, params SqlParameter[] parameters)
{
return ExecuteReader(CreateCommand(connectionString, commandText, commandType, parameters), commandBehavior);
}
///
/// Creates a SqlDataReader for the given SqlCommand.
///
/// The SqlCommand to be executed.
/// One of the CommandBehavior values.
///
/// The SqlDataReader.
///
public static SqlDataReader ExecuteReader(this SqlCommand command, CommandBehavior commandBehavior)
{
if(command.Connection.State == ConnectionState.Closed)
{
command.Connection.Open();
}
return command.ExecuteReader(commandBehavior);
}
#endregion
#region ExecuteXmlReader Method
///
/// Invokes readerHandler with the XmlReader
/// created for the given Transact-SQL statement or stored procedure
/// with the given (optional) parameters.
///
/// The sql connection string.
/// The Transact-SQL statement or
/// stored procedure to execute.
///
/// A value indicating how the commandText
/// value is to be interpreted.
///
/// A method for consuming the generated reader.
///
/// The array of SqlParameters
/// to be queried.
/// If null or zero-length then no parameters are added.
///
/// The result of the Transact-SQL statement.
/// The type of the result returned.
/// If handler is null.
public static T ExecuteReader(string connectionString, string commandText, CommandType commandType, XmlReaderHandler handler, params SqlParameter[] parameters)
{
return ExecuteReader(CreateCommand(connectionString, commandText, commandType, parameters), handler);
}
///
/// Invokes readerHandler with the XmlReader
/// created for the given SqlCommand.
///
/// This method closes and disposes the
/// SqlConnection and disposes the SqlCommand
/// after the readerHandler returns.
///
///
/// The SqlCommand to be executed.
///
/// A method for consuming the generated reader.
///
/// The results of executing readerHandler.
/// The type of the result to be returned.
/// If handler is null.
public static T ExecuteReader(this SqlCommand command, XmlReaderHandler handler)
{
if(handler != null)
{
return ExecuteCommand(command,
delegate(SqlCommand cmd)
{
using(var reader = cmd.ExecuteXmlReader())
{
return handler(reader);
}
});
}
throw new ArgumentNullException("handler");
}
#endregion
#region AddParameters Method
///
/// Adds the given parameters to the given parameterized command.
///
/// The parameterized command to be queried.
/// The parameters of the Transact-SQL statement
/// or stored procedure. May be null or must contain
/// SqlParameter's or an even number of
/// parameterName-parameterValue pairs.
///
public static void AddParameters(this SqlCommand command, params object[] parameters)
{
if(parameters != null && parameters.Length > 0)
{
for(var i = 0; i < parameters.Length; i += 2)
{
if(parameters[i] is SqlParameter)
{
command.Parameters.Add((SqlParameter)parameters[i]);
if(i < parameters.Length)
{
command.Parameters.Add((SqlParameter)parameters[i + 1]);
}
}
else
{
command.Parameters.AddWithValue(parameters[i].ToString(), parameters[i + 1]);
}
}
}
}
#endregion
#region Convert To DbType
///
/// Converts the given Type to a DbType.
///
/// The type to be queried.
/// A DbType.
public static DbType ConvertToDbType(Type type)
{
// HACK : ToDbType
if(type == typeof(Int16))
{
return DbType.Int16;
}
if(type == typeof(Int32))
{
return DbType.Int32;
}
if(type == typeof(Int64))
{
return DbType.Int64;
}
if(type == typeof(Boolean))
{
return DbType.Boolean;
}
if(type == typeof(Byte))
{
return DbType.Byte;
}
if(type == typeof(DateTime))
{
return DbType.DateTime;
}
if(type == typeof(Double))
{
return DbType.Double;
}
if(type == typeof(Decimal))
{
return DbType.Decimal;
}
if(type == typeof(Guid))
{
return DbType.Guid;
}
if(type == typeof(SByte))
{
return DbType.SByte;
}
if(type == typeof(Single))
{
return DbType.Single;
}
if(type == typeof(String))
{
return DbType.AnsiString; // varchar
}
if(type == typeof(XmlDocument))
{
return DbType.Xml;
}
return DbType.Object;
//object dummyInstance = Activator.CreateInstance(type);
// We don't care what type of parameter we use;
// the parameter is going to get thrown away.
// Basically, we're creating a pseudointerface
// to code hidden inside the parameter constructor.
//SqlParameter dummyParameter = new SqlParameter("dummyname", dummyInstance);
//return dummyParameter.DbType;
}
#endregion
}
#region Delegate Declarations
///
/// A delegate for a method that processes an SqlDataReader
/// and returns the results of that process.
///
/// The SqlDataReader to be queried.
/// The results of processing the SqlDataReader.
/// The type of the result returned.
public delegate T DataReaderHandler(SqlDataReader reader);
///
/// A delegate for a method that handles an XmlReader
/// and returns the results of that process.
///
/// The XmlReader to be queried.
/// The results of processing the XmlReader.
/// The type of the result returned.
public delegate T XmlReaderHandler(XmlReader reader);
///
/// A delegate for a method that handles an IDbCommand
/// and returns the results of that process.
///
/// The IDbCommand to be executed.
/// The results of processing the IDbCommand.
/// The type of the result returned.
public delegate T CommandHandler(SqlCommand command);
#endregion
}