using System;
using System.Collections;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Data.Common;
using System.Data.SqlTypes;
using System.Diagnostics;
using System.Text;
namespace BLToolkit.Data
{
using Common;
using DataProvider;
using Mapping;
using Properties;
using Reflection;
using Sql;
///
/// The DbManager is a primary class of the namespace
/// that can be used to execute commands of different database providers.
///
///
/// When the DbManager goes out of scope, it does not close the internal connection object.
/// Therefore, you must explicitly close the connection by calling or
/// . Also, you can use the C# using statement.
///
///
[DesignerCategory("Code")]
public partial class DbManager: Component
{
#region Constructors
public DbManager(DataProviderBase dataProvider, string connectionString)
{
if (dataProvider == null) throw new ArgumentNullException("dataProvider");
if (connectionString == null) throw new ArgumentNullException("connectionString");
_dataProvider = dataProvider;
_connection = dataProvider.CreateConnectionObject();
_connection.ConnectionString = connectionString;
_dataProvider.InitDbManager(this);
}
public DbManager(DataProviderBase dataProvider, IDbConnection connection)
{
if (dataProvider == null) throw new ArgumentNullException("dataProvider");
if (connection == null) throw new ArgumentNullException("connection");
_dataProvider = dataProvider;
_connection = connection;
_dataProvider.InitDbManager(this);
}
public DbManager(DataProviderBase dataProvider, IDbTransaction transaction)
{
if (dataProvider == null) throw new ArgumentNullException("dataProvider");
if (transaction == null) throw new ArgumentNullException("transaction");
_dataProvider = dataProvider;
_connection = transaction.Connection;
_transaction = transaction;
_closeTransaction = false;
_dataProvider.InitDbManager(this);
}
DbManager(int n)
{
}
public DbManager Clone()
{
DbManager clone = new DbManager(0);
clone._configurationString = _configurationString;
clone._dataProvider = _dataProvider;
clone._mappingSchema = _mappingSchema;
if (_connection != null)
clone._connection = CloneConnection();
return clone;
}
#endregion
#region Public Properties
private MappingSchema _mappingSchema = Map.DefaultSchema;
///
/// Gets the
/// used by this instance of the .
///
///
/// A mapping schema.
///
public MappingSchema MappingSchema
{
[DebuggerStepThrough]
get { return _mappingSchema; }
set { _mappingSchema = value ?? Map.DefaultSchema; }
}
private DataProviderBase _dataProvider;
///
/// Gets the
/// used by this instance of the .
///
///
/// A data provider.
///
///
public DataProviderBase DataProvider
{
[DebuggerStepThrough]
get { return _dataProvider; }
protected set { _dataProvider = value; }
}
private static TraceSwitch _traceSwitch;
public static TraceSwitch TraceSwitch
{
get { return _traceSwitch ?? (_traceSwitch = new TraceSwitch("DbManager", "DbManager trace switch", "Warning")); }
set { _traceSwitch = value; }
}
private bool _canRaiseEvents = true;
public new bool CanRaiseEvents
{
get { return _canRaiseEvents && base.CanRaiseEvents; }
set { _canRaiseEvents = value; }
}
#endregion
#region Connection
private bool _closeConnection;
private IDbConnection _connection;
///
/// Gets or sets the used by this instance of the .
///
///
/// The connection to the data source.
///
///
/// Then you set a connection object, it has to match the data source type.
///
///
/// A connection does not match the data source type.
///
///
public IDbConnection Connection
{
[DebuggerStepThrough]
get
{
if (_connection.State == ConnectionState.Closed)
OpenConnection();
return _connection;
}
set
{
if (value == null)
throw new ArgumentNullException("value");
if (value.GetType() != _dataProvider.ConnectionType)
InitDataProvider(value);
_connection = value;
_closeConnection = false;
}
}
[Obsolete]
protected virtual string GetConnectionString(IDbConnection connection)
{
return connection.ConnectionString;
}
private void OpenConnection()
{
ExecuteOperation(OperationType.OpenConnection, _connection.Open);
_closeConnection = true;
}
///
/// Closes the connection to the database.
///
///
/// The Close method rolls back any pending transactions
/// and then closes the connection.
///
///
///
public void Close()
{
if (OnClosing != null)
OnClosing(this, EventArgs.Empty);
if (_selectCommand != null) { _selectCommand.Dispose(); _selectCommand = null; }
if (_insertCommand != null) { _insertCommand.Dispose(); _insertCommand = null; }
if (_updateCommand != null) { _updateCommand.Dispose(); _updateCommand = null; }
if (_deleteCommand != null) { _deleteCommand.Dispose(); _deleteCommand = null; }
if (_transaction != null && _closeTransaction)
{
ExecuteOperation(OperationType.DisposeTransaction, _transaction.Dispose);
_transaction = null;
}
if (_connection != null && _closeConnection)
{
ExecuteOperation(OperationType.CloseConnection, _connection.Dispose);
_connection = null;
}
if (OnClosed != null)
OnClosed(this, EventArgs.Empty);
}
#endregion
#region Transactions
private bool _closeTransaction = true;
private IDbTransaction _transaction;
///
/// Gets the used by this instance of the .
///
///
/// The . The default value is a null reference.
///
///
/// You have to call the method to begin a transaction.
///
///
///
public IDbTransaction Transaction
{
[DebuggerStepThrough]
get { return _transaction; }
}
///
/// Begins a database transaction.
///
///
/// Once the transaction has completed, you must explicitly commit or roll back the transaction
/// by using the > or
/// methods.
///
///
/// This instance of the .
///
public virtual DbManager BeginTransaction()
{
return BeginTransaction(IsolationLevel.ReadCommitted);
}
///
/// Begins a database transaction with the specified value.
///
///
/// Once the transaction has completed, you must explicitly commit or roll back the transaction
/// by using the or
/// methods.
///
///
/// One of the values.
/// This instance of the .
public virtual DbManager BeginTransaction(IsolationLevel il)
{
// If transaction is open, we dispose it, it will rollback all changes.
//
if (_transaction != null)
{
ExecuteOperation(OperationType.DisposeTransaction, _transaction.Dispose);
}
// Create new transaction object.
//
_transaction = ExecuteOperation(OperationType.BeginTransaction,
delegate { return Connection.BeginTransaction(il); });
_closeTransaction = true;
// If the active command exists.
//
if (_selectCommand != null) _selectCommand.Transaction = _transaction;
if (_insertCommand != null) _insertCommand.Transaction = _transaction;
if (_updateCommand != null) _updateCommand.Transaction = _transaction;
if (_deleteCommand != null) _deleteCommand.Transaction = _transaction;
return this;
}
///
/// Commits the database transaction.
///
/// This instance of the .
public virtual DbManager CommitTransaction()
{
if (_transaction != null)
{
ExecuteOperation(OperationType.CommitTransaction, _transaction.Commit);
if (_closeTransaction)
_transaction = null;
}
return this;
}
///
/// Rolls back a transaction from a pending state.
///
/// This instance of the .
public virtual DbManager RollbackTransaction()
{
if (_transaction != null)
{
ExecuteOperation(OperationType.RollbackTransaction, _transaction.Rollback);
if (_closeTransaction)
_transaction = null;
}
return this;
}
#endregion
#region Commands
private IDbCommand _selectCommand;
///
/// Gets the used by this instance of the .
///
///
/// A used during executing query.
///
///
/// The Command can be used to access command parameters.
///
///
public IDbCommand Command
{
[DebuggerStepThrough]
get { return SelectCommand; }
}
///
/// Gets the select used by this instance of the .
///
///
/// A used during executing query.
///
///
/// The SelectCommand can be used to access select command parameters.
///
///
public IDbCommand SelectCommand
{
[DebuggerStepThrough]
get { return _selectCommand = OnInitCommand(_selectCommand); }
}
private IDbCommand _insertCommand;
///
/// Gets the insert used by this instance of the .
///
///
/// A used during executing query.
///
///
/// The InsertCommand can be used to access insert command parameters.
///
///
public IDbCommand InsertCommand
{
[DebuggerStepThrough]
get { return _insertCommand = OnInitCommand(_insertCommand); }
}
private IDbCommand _updateCommand;
///
/// Gets the update used by this instance of the .
///
///
/// A used during executing query.
///
///
/// The UpdateCommand can be used to access update command parameters.
///
///
public IDbCommand UpdateCommand
{
[DebuggerStepThrough]
get { return _updateCommand = OnInitCommand(_updateCommand); }
}
private IDbCommand _deleteCommand;
///
/// Gets the delete used by this instance of the .
///
///
/// A used during executing query.
///
///
/// The DeleteCommand can be used to access delete command parameters.
///
///
public IDbCommand DeleteCommand
{
[DebuggerStepThrough]
get { return _deleteCommand = OnInitCommand(_deleteCommand); }
}
///
/// Initializes a command and raises the event.
///
protected virtual IDbCommand OnInitCommand(IDbCommand command)
{
if (command == null)
{
// Create a command object.
//
command = _dataProvider.CreateCommandObject(Connection);
// If an active transaction exists.
//
if (Transaction != null)
{
command.Transaction = Transaction;
}
}
if (CanRaiseEvents)
{
InitCommandEventHandler handler = (InitCommandEventHandler)Events[EventInitCommand];
if (handler != null)
handler(this, new InitCommandEventArgs(command));
}
return command;
}
///
/// Helper function. Creates the command object and sets command type and command text.
///
/// Command action.
/// The
/// (stored procedure, text, etc.)
/// The SQL statement.
/// The command object.
private IDbCommand GetCommand(CommandAction commandAction, CommandType commandType, string sql)
{
IDbCommand command = GetCommand(commandAction);
command.Parameters.Clear();
command.CommandType = commandType;
command.CommandText = sql;
return command;
}
#endregion
#region Events
public event EventHandler OnClosing;
public event EventHandler OnClosed;
private static readonly object EventBeforeOperation = new object();
///
/// Occurs when a server-side operation is about to start.
///
public event OperationTypeEventHandler BeforeOperation
{
add { Events.AddHandler (EventBeforeOperation, value); }
remove { Events.RemoveHandler(EventBeforeOperation, value); }
}
private static readonly object EventAfterOperation = new object();
///
/// Occurs when a server-side operation is complete.
///
public event OperationTypeEventHandler AfterOperation
{
add { Events.AddHandler (EventAfterOperation, value); }
remove { Events.RemoveHandler(EventAfterOperation, value); }
}
private static readonly object EventOperationException = new object();
///
/// Occurs when a server-side operation is failed to execute.
///
public event OperationExceptionEventHandler OperationException
{
add { Events.AddHandler (EventOperationException, value); }
remove { Events.RemoveHandler(EventOperationException, value); }
}
private static readonly object EventInitCommand = new object();
///
/// Occurs when the is initializing.
///
public event InitCommandEventHandler InitCommand
{
add { Events.AddHandler (EventInitCommand, value); }
remove { Events.RemoveHandler(EventInitCommand, value); }
}
///
/// Raises the event.
///
/// The .
protected virtual void OnBeforeOperation(OperationType op)
{
if (CanRaiseEvents)
{
OperationTypeEventHandler handler = (OperationTypeEventHandler)Events[EventBeforeOperation];
if (handler != null)
handler(this, new OperationTypeEventArgs(op));
}
}
///
/// Raises the event.
///
/// The .
protected virtual void OnAfterOperation(OperationType op)
{
if (CanRaiseEvents)
{
OperationTypeEventHandler handler = (OperationTypeEventHandler)Events[EventAfterOperation];
if (handler != null)
handler(this, new OperationTypeEventArgs(op));
}
}
///
/// Raises the event.
///
/// The .
/// The occurred.
protected virtual void OnOperationException(OperationType op, DataException ex)
{
if (CanRaiseEvents)
{
OperationExceptionEventHandler handler = (OperationExceptionEventHandler)Events[EventOperationException];
if (handler != null)
handler(this, new OperationExceptionEventArgs(op, ex));
}
throw ex;
}
#endregion
#region Protected Methods
private IDataReader ExecuteReaderInternal()
{
return ExecuteReader(CommandBehavior.Default);
}
private IDataReader ExecuteReaderInternal(CommandBehavior commandBehavior)
{
return ExecuteOperation(OperationType.ExecuteReader, delegate
{
return _dataProvider.GetDataReader(_mappingSchema, SelectCommand.ExecuteReader(commandBehavior));
});
}
private int ExecuteNonQueryInternal()
{
return ExecuteOperation(OperationType.ExecuteNonQuery, SelectCommand.ExecuteNonQuery);
}
#endregion
#region Parameters
private IDbDataParameter[] CreateSpParameters(string spName, object[] parameterValues, bool openNewConnectionToDiscoverParameters)
{
// Pull the parameters for this stored procedure from
// the parameter cache (or discover them & populate the cache)
//
IDbDataParameter[] commandParameters = GetSpParameters(spName, true, openNewConnectionToDiscoverParameters);
// DbParameters are bound by name, plain parameters by order
//
bool dbParameters = false;
if (parameterValues == null || parameterValues.Length == 0 ||
parameterValues[0] is IDbDataParameter || parameterValues[0] is IDbDataParameter[])
{
// The PrepareParameters method may add some additional parameters.
//
parameterValues = PrepareParameters(parameterValues);
if (parameterValues == null || parameterValues.Length == 0)
return commandParameters;
dbParameters = true;
}
if (commandParameters == null/* || commandParameters.Length == 0*/)
{
commandParameters = new IDbDataParameter[parameterValues.Length];
if (dbParameters)
{
parameterValues.CopyTo(commandParameters, 0);
}
else
{
for (int i = 0; i < parameterValues.Length; i++)
commandParameters[i] = Parameter("?", parameterValues[i]);
}
return commandParameters;
}
if (dbParameters)
{
// If we receive an array of IDbDataParameter,
// we need to copy parameters to the IDbDataParameter[].
//
for (int i = 0; i < commandParameters.Length; i++)
{
IDbDataParameter param = commandParameters[i];
string name = param.ParameterName;
bool found = false;
foreach (IDbDataParameter p in parameterValues)
{
if (string.Compare(name, p.ParameterName, true) == 0)
{
if (param.Direction != p.Direction)
{
Debug.WriteLineIf(TraceSwitch.TraceWarning, string.Format(
"Stored Procedure '{0}'. Parameter '{1}' has different direction '{2}'. Should be '{3}'.",
spName, name, param.Direction, p.Direction),
TraceSwitch.DisplayName);
param.Direction = p.Direction;
}
if (param.Direction != ParameterDirection.Output)
param.Value = p.Value;
p.ParameterName = name;
found = true;
break;
}
}
if (found == false && (
param.Direction == ParameterDirection.Input ||
param.Direction == ParameterDirection.InputOutput))
{
Debug.WriteLineIf(TraceSwitch.TraceWarning, string.Format(
"Stored Procedure '{0}'. Parameter '{1}' not assigned.", spName, name),
TraceSwitch.DisplayName);
param.SourceColumn = _dataProvider.Convert(name, ConvertType.ParameterToName).ToString();
}
}
}
else
{
// Assign the provided values to the parameters based on parameter order.
//
AssignParameterValues(commandParameters, parameterValues);
}
return commandParameters;
}
///
/// Creates an one-dimension array of
/// from any combination on IDbDataParameter, IDbDataParameter[] or null references.
/// Null references are stripped, arrays and single parameters are combined
/// into a new array.
///
/// When two or more parameters has the same name,
/// the first parameter is used, all the rest are ignored.
///Array of IDbDataParameter, IDbDataParameter[] or null references.
///An normalized array of without null references.
///The parameter
/// contains anything except IDbDataParameter, IDbDataParameter[] or null reference.
public virtual IDbDataParameter[] PrepareParameters(object[] parameters)
{
if (parameters == null || parameters.Length == 0)
return null;
// Little optimization.
// Check if we have only one single ref parameter.
//
object refParam = null;
for (int i = 0; i < parameters.Length; i++)
{
if (parameters[i] != null)
{
if (refParam != null)
{
refParam = null;
break;
}
refParam = parameters[i];
}
}
if (refParam is IDbDataParameter[])
{
return (IDbDataParameter[])refParam;
}
if (refParam is IDbDataParameter)
{
IDbDataParameter[] oneParameterArray = new IDbDataParameter[1];
oneParameterArray[0] = (IDbDataParameter)refParam;
return oneParameterArray;
}
List list = new List(parameters.Length);
Dictionary hash = new Dictionary(parameters.Length);
foreach (object o in parameters)
{
if (o is IDbDataParameter)
{
IDbDataParameter p = (IDbDataParameter)o;
if (!hash.ContainsKey(p.ParameterName))
{
list.Add(p);
hash.Add(p.ParameterName, p);
}
}
else if (o is IDbDataParameter[])
{
foreach (IDbDataParameter p in (IDbDataParameter[])o)
{
if (!hash.ContainsKey(p.ParameterName))
{
list.Add(p);
hash.Add(p.ParameterName, p);
}
}
}
else if (o != null && o != DBNull.Value)
{
throw new ArgumentException(
Resources.DbManager_NotDbDataParameter, "parameters");
}
}
return list.ToArray();
}
///
/// This method is used to attach array of to a .
///
/// The command to which the parameters will be added
/// An array of IDbDataParameters tho be added to command
private void AttachParameters(IDbCommand command, IDbDataParameter[] commandParameters)
{
command.Parameters.Clear();
foreach (IDbDataParameter p in commandParameters)
{
_dataProvider.AttachParameter(command, p);
}
}
private static readonly Dictionary _paramCache =
new Dictionary();
private static readonly object _paramCacheLock = new object();
///
/// Resolve at run time the appropriate set of parameters for a stored procedure.
///
/// The name of the stored procedure.
/// Whether or not to include their return value parameter.
///
protected virtual IDbDataParameter[] DiscoverSpParameters(string spName, bool includeReturnValueParameter, bool openNewConnection)
{
IDbConnection con = openNewConnection ? CloneConnection() : _connection;
try
{
if (con.State == ConnectionState.Closed)
{
ExecuteOperation(OperationType.OpenConnection, con.Open);
if (!openNewConnection)
_closeConnection = true;
}
using (IDbCommand cmd = con.CreateCommand())
{
cmd.CommandType = CommandType.StoredProcedure;
cmd.CommandText = spName;
bool res = ExecuteOperation(OperationType.DeriveParameters, delegate { return _dataProvider.DeriveParameters(cmd); });
ExecuteOperation(OperationType.CloseConnection, con.Close);
if (res == false)
return null;
if (includeReturnValueParameter == false)
{
// All known data providers always treat
// the return value as first parameter.
//
cmd.Parameters.RemoveAt(0);
}
IDbDataParameter[] discoveredParameters =
new IDbDataParameter[cmd.Parameters.Count];
cmd.Parameters.CopyTo(discoveredParameters, 0);
return discoveredParameters;
}
}
finally
{
if (con != null && openNewConnection)
con.Dispose();
}
}
///
/// Copies cached parameter array.
///
/// The original parameter array.
/// The result array.
private IDbDataParameter[] CloneParameters(IDbDataParameter[] originalParameters)
{
if (originalParameters == null)
return null;
IDbDataParameter[] clonedParameters = new IDbDataParameter[originalParameters.Length];
for (int i = 0, j = originalParameters.Length; i < j; i++)
{
clonedParameters[i] = _dataProvider.CloneParameter(originalParameters[i]);
}
return clonedParameters;
}
///
/// Retrieves the set of parameters appropriate for the stored procedure.
///
///
/// This method will query the database for this information,
/// and then store it in a cache for future requests.
///
/// The name of the stored procedure.
/// A boolean value indicating
/// whether the return value parameter should be included in the results.
/// An array of the .
public IDbDataParameter[] GetSpParameters(string spName, bool includeReturnValueParameter, bool openNewConnectionToDiscoverParameters)
{
string key = string.Format("{0}:{1}:{2}", GetConnectionHash(), spName, includeReturnValueParameter);
IDbDataParameter[] cachedParameters;
// It is thread safe enought to check for a key and get its value without a lock.
//
if (!_paramCache.TryGetValue(key, out cachedParameters))
{
lock (_paramCacheLock)
{
// There is a possible race condition since the operation may took a time.
//
if (!_paramCache.TryGetValue(key, out cachedParameters))
{
cachedParameters = DiscoverSpParameters(spName, includeReturnValueParameter, openNewConnectionToDiscoverParameters);
_paramCache.Add(key, cachedParameters);
}
}
}
return CloneParameters(cachedParameters);
}
///
/// This method assigns an array of values to an array of parameters.
///
/// array of IDbDataParameters to be assigned values
/// array of objects holding the values to be assigned
private void AssignParameterValues(IDbDataParameter[] commandParameters, object[] parameterValues)
{
if (commandParameters == null || parameterValues == null)
{
// Do nothing if we get no data.
//
return;
}
int nValues = 0;
// Iterate through the parameters, assigning the values from
// the corresponding position in the value array.
//
for (int i = 0; i < commandParameters.Length; i++)
{
IDbDataParameter parameter = commandParameters[i];
if (_dataProvider.IsValueParameter(parameter))
{
if (nValues >= parameterValues.Length)
throw new ArgumentException(Resources.DbManager_MismatchParameterCount);
object value = parameterValues[nValues++];
parameter.Value = value ?? DBNull.Value;
//_dataProvider.SetParameterType(parameter, value);
}
}
// We must have the same number of values as we pave parameters to put them in.
//
if (nValues != parameterValues.Length)
throw new ArgumentException(Resources.DbManager_MismatchParameterCount);
}
///
/// Assigns a business object to command parameters.
///
///
/// Assigns the to command parameters.
///
///
///
/// The method is used in addition to the method.
///
/// The to assign.
/// This instance of the .
public DbManager AssignParameterValues(DataRow dataRow)
{
if (dataRow == null)
throw new ArgumentNullException("dataRow");
foreach (DataColumn c in dataRow.Table.Columns)
{
if (c.AutoIncrement == false && c.ReadOnly == false)
{
object o = dataRow[c.ColumnName];
string name = _dataProvider.Convert(c.ColumnName, ConvertType.NameToParameter).ToString();
Parameter(name).Value =
c.AllowDBNull && _mappingSchema.IsNull(o)? DBNull.Value: o;
}
}
if (_prepared)
InitParameters(CommandAction.Select);
return this;
}
///
/// Assigns a business object to command parameters.
///
///
/// The method is used in addition to the method.
///
///
/// An object to assign.
/// This instance of the .
public DbManager AssignParameterValues(object obj)
{
if (obj == null)
throw new ArgumentNullException("obj");
ObjectMapper om = _mappingSchema.GetObjectMapper(obj.GetType());
foreach (MemberMapper mm in om)
{
string name = _dataProvider.Convert(mm.Name, ConvertType.NameToParameter).ToString();
if (Command.Parameters.Contains(name))
{
object value = mm.GetValue(obj);
Parameter(name).Value =
value == null || mm.MapMemberInfo.Nullable && _mappingSchema.IsNull(value)?
DBNull.Value: value;
}
}
if (_prepared)
InitParameters(CommandAction.Select);
return this;
}
private static Array SortArray(Array array, IComparer comparer)
{
if (array == null)
return null;
Array arrayClone = (Array)array.Clone();
Array.Sort(arrayClone, comparer);
return arrayClone;
}
///
/// Creates an array of parameters from the object.
///
///
/// The method can take an additional parameter list,
/// which can be created by using the same method.
///
///
/// The to create parameters.
/// An array of parameters to be added to the result array.
/// An array of parameters.
public IDbDataParameter[] CreateParameters(
DataRow dataRow, params IDbDataParameter[] commandParameters)
{
return CreateParameters(dataRow, null, null, null, commandParameters);
}
///
/// Creates an array of parameters from the object.
///
///
/// The method can take an additional parameter list,
/// which can be created by using the same method.
///
///
/// The to create parameters.
/// Output parameters names.
/// InputOutput parameters names.
/// Parameters names to skip.
/// An array of parameters to be added to the result array.
/// An array of parameters.
public IDbDataParameter[] CreateParameters(
DataRow dataRow,
string[] outputParameters,
string[] inputOutputParameters,
string[] ignoreParameters,
params IDbDataParameter[] commandParameters)
{
if (dataRow == null)
throw new ArgumentNullException("dataRow");
ArrayList paramList = new ArrayList();
IComparer comparer = CaseInsensitiveComparer.Default;
outputParameters = (string[])SortArray(outputParameters, comparer);
inputOutputParameters = (string[])SortArray(inputOutputParameters, comparer);
ignoreParameters = (string[])SortArray(ignoreParameters, comparer);
foreach (DataColumn c in dataRow.Table.Columns)
{
if (ignoreParameters != null && Array.BinarySearch(ignoreParameters, c.ColumnName, comparer) >= 0)
continue;
if (c.AutoIncrement || c.ReadOnly)
continue;
string name = _dataProvider.Convert(c.ColumnName, ConvertType.NameToParameter).ToString();
IDbDataParameter parameter = c.AllowDBNull?
NullParameter(name, dataRow[c.ColumnName]):
Parameter (name, dataRow[c.ColumnName]);
if (outputParameters != null && Array.BinarySearch(outputParameters, c.ColumnName, comparer) >= 0)
parameter.Direction = ParameterDirection.Output;
else if (inputOutputParameters != null && Array.BinarySearch(inputOutputParameters, c.ColumnName, comparer) >= 0)
parameter.Direction = ParameterDirection.InputOutput;
paramList.Add(parameter);
}
if (commandParameters != null)
paramList.AddRange(commandParameters);
return (IDbDataParameter[])paramList.ToArray(typeof(IDbDataParameter));
}
///
/// Creates an array of parameters from a business object.
///
///
/// The method can take an additional parameter list,
/// which can be created by using the same method.
///
///
/// An object.
/// An array of parameters to be added to the result array.
/// An array of parameters.
public IDbDataParameter[] CreateParameters(
object obj,
params IDbDataParameter[] commandParameters)
{
return CreateParameters(obj, null, null, null, commandParameters);
}
///
/// Creates an array of parameters from a business object.
///
///
/// The method can take an additional parameter list,
/// which can be created by using the same method.
///
///
/// An object.
/// Output parameters names.
/// InputOutput parameters names.
/// Parameters names to skip.
/// An array of parameters to be added to the result array.
/// An array of parameters.
public IDbDataParameter[] CreateParameters(
object obj,
string[] outputParameters,
string[] inputOutputParameters,
string[] ignoreParameters,
params IDbDataParameter[] commandParameters)
{
if (obj == null)
throw new ArgumentNullException("obj");
bool isType = obj is Type;
Type type = isType? (Type)obj: obj.GetType();
ObjectMapper om = _mappingSchema.GetObjectMapper(type);
ArrayList paramList = new ArrayList();
IComparer comparer = CaseInsensitiveComparer.Default;
outputParameters = (string[])SortArray(outputParameters, comparer);
inputOutputParameters = (string[])SortArray(inputOutputParameters, comparer);
ignoreParameters = (string[])SortArray(ignoreParameters, comparer);
foreach (MemberMapper mm in om)
{
if (ignoreParameters != null && Array.BinarySearch(ignoreParameters, mm.Name, comparer) >= 0)
continue;
object value = isType? null: mm.GetValue(obj);
string name = _dataProvider.Convert(mm.Name, ConvertType.NameToParameter).ToString();
IDbDataParameter parameter = mm.MapMemberInfo.Nullable || value == null?
NullParameter(name, value, mm.MapMemberInfo.NullValue): (mm.DbType != DbType.Object)?
Parameter (name, value, mm.DbType ):
Parameter (name, value);
if (outputParameters != null && Array.BinarySearch(outputParameters, mm.Name, comparer) >= 0)
parameter.Direction = ParameterDirection.Output;
else if (inputOutputParameters != null && Array.BinarySearch(inputOutputParameters, mm.Name, comparer) >= 0)
parameter.Direction = ParameterDirection.InputOutput;
paramList.Add(parameter);
}
if (commandParameters != null)
paramList.AddRange(commandParameters);
return (IDbDataParameter[])paramList.ToArray(typeof(IDbDataParameter));
}
///
/// Maps all parameters returned from the server to all given objects.
///
/// Name of a to map return value.
/// An to map from command parameters.
public void MapOutputParameters(
string returnValueMember,
object obj)
{
IMapDataDestination dest = _mappingSchema.GetDataDestination(obj);
foreach (IDbDataParameter parameter in Command.Parameters)
{
int ordinal = -1;
switch (parameter.Direction)
{
case ParameterDirection.InputOutput:
case ParameterDirection.Output:
ordinal = dest.GetOrdinal(
_dataProvider.Convert(parameter.ParameterName, ConvertType.ParameterToName).ToString());
break;
case ParameterDirection.ReturnValue:
if (returnValueMember != null)
{
if (!returnValueMember.StartsWith("@") && dest is ObjectMapper)
{
ObjectMapper om = (ObjectMapper)dest;
MemberAccessor ma = om.TypeAccessor[returnValueMember];
if (ma != null)
{
ma.SetValue(obj, _mappingSchema.ConvertChangeType(parameter.Value, ma.Type));
continue;
}
}
else
{
returnValueMember = returnValueMember.Substring(1);
}
ordinal = dest.GetOrdinal(returnValueMember);
}
break;
}
if (ordinal >= 0)
dest.SetValue(obj, ordinal, _mappingSchema.ConvertChangeType(parameter.Value, dest.GetFieldType(ordinal)));
}
}
///
/// Maps all parameters returned from the server to an object.
///
/// An to map from command parameters.
/// from command parameters.
public void MapOutputParameters(object obj)
{
MapOutputParameters(null, obj);
}
///
/// Maps all parameters returned from the server to all given objects.
///
/// Name of the member used to map the
/// return value. Can be null.
/// An array of to map
/// from command parameters.
public void MapOutputParameters(string returnValueMember, params object[] objects)
{
if (objects == null)
return;
foreach (object obj in objects)
MapOutputParameters(returnValueMember, obj);
}
///
/// Maps all parameters returned from the server to an object.
///
/// An array of to map
/// from command parameters.
public void MapOutputParameters(params object[] objects)
{
MapOutputParameters(null, objects);
}
///
/// Adds a parameter to the or returns existing one.
///
///
/// Returns an existing parameter.
///
///
/// The method can be used to retrieve return and output parameters.
///
///
/// The name of the parameter.
/// The object.
public IDbDataParameter Parameter(string parameterName)
{
return _dataProvider.GetParameter(Command, parameterName);
}
///
/// Adds an input parameter to the .
///
///
/// The method creates a parameter with the
/// ParameterDirection.Input type.
///
///
/// The name of the parameter.
/// The
/// that is the value of the parameter.
/// The object.
public IDbDataParameter Parameter(string parameterName, object value)
{
return Parameter(ParameterDirection.Input, parameterName, value);
}
///
/// Adds an input parameter to the .
///
///
/// The method creates a parameter with the
/// ParameterDirection.Input type.
///
/// The name of the parameter.
/// One of the values.
/// The object.
public IDbDataParameter Parameter(string parameterName, DbType dbType)
{
return Parameter(ParameterDirection.Input, parameterName, dbType);
}
///
/// Adds an input parameter to the .
///
///
/// The method creates a parameter with the
/// ParameterDirection.Input type.
///
/// The name of the parameter.
/// One of the values.
/// Size of the parameter.
/// The object.
public IDbDataParameter Parameter(string parameterName, DbType dbType, int size)
{
return Parameter(ParameterDirection.Input, parameterName, dbType, size);
}
///
/// Adds an input parameter to the .
///
///
/// The method creates a parameter with the
/// ParameterDirection.Input type.
/// If the parameter is null, it's converted to ..
///
///
/// The name of the parameter.
/// The
/// that is the value of the parameter.
/// The object.
public IDbDataParameter NullParameter(string parameterName, object value)
{
if (_mappingSchema.IsNull(value))
@value = DBNull.Value;
return Parameter(ParameterDirection.Input, parameterName, value);
}
///
/// Adds an input parameter to the .
///
///
/// The method creates a parameter with the
/// ParameterDirection.Input type.
///
/// The name of the parameter.
/// The
/// that is the value of the parameter.
/// The null equivalent to compare with the value.
/// The object.
public IDbDataParameter NullParameter(string parameterName, object value, object nullValue)
{
if (value == null || value.Equals(nullValue))
@value = DBNull.Value;
return Parameter(ParameterDirection.Input, parameterName, value);
}
///
/// Adds an input parameter to the .
///
///
/// The method creates a parameter with the
/// ParameterDirection.Input type.
///
/// The name of the parameter.
/// The
/// that is the value of the parameter.
/// The object.
public IDbDataParameter InputParameter(string parameterName, object value)
{
return Parameter(ParameterDirection.Input, parameterName, value);
}
///
/// Adds an output parameter to the .
///
///
/// The method creates a parameter with the
/// ParameterDirection.Output type.
///
/// The name of the parameter.
/// The
/// that is the value of the parameter.
/// The object.
public IDbDataParameter OutputParameter(string parameterName, object value)
{
return Parameter(ParameterDirection.Output, parameterName, value);
}
///
/// Adds an output parameter to the .
///
///
/// The method creates a parameter with the
/// ParameterDirection.Output type.
///
/// The name of the parameter.
/// One of the values.
/// that is the value of the parameter.
/// The object.
public IDbDataParameter OutputParameter(string parameterName, DbType dbType)
{
return Parameter(ParameterDirection.Output, parameterName, dbType);
}
///
/// Adds an output parameter to the .
///
///
/// The method creates a parameter with the
/// ParameterDirection.Output type.
///
/// The name of the parameter.
/// One of the values.
/// Size of the parameter.
/// that is the value of the parameter.
/// The object.
public IDbDataParameter OutputParameter(string parameterName, DbType dbType, int size)
{
return Parameter(ParameterDirection.Output, parameterName, dbType, size);
}
///
/// Adds an input-output parameter to the .
///
///
/// The method creates a parameter with the
/// ParameterDirection.InputOutput type.
///
/// The name of the parameter.
/// The
/// that is the value of the parameter.
/// The object.
public IDbDataParameter InputOutputParameter(string parameterName, object value)
{
return Parameter(ParameterDirection.InputOutput,parameterName, value);
}
///
/// Adds a return value parameter to the .
///
///
/// The method creates a parameter with the
/// ParameterDirection.ReturnValue type.
///
/// The name of the parameter.
/// The object.
public IDbDataParameter ReturnValue(string parameterName)
{
return Parameter(ParameterDirection.ReturnValue, parameterName, null);
}
///
/// Adds a parameter to the .
///
///
/// The method creates a parameter with the specified
/// type.
///
/// One of the values.
/// The name of the parameter.
/// The
/// that is the value of the parameter.
/// The object.
public IDbDataParameter Parameter(
ParameterDirection parameterDirection,
string parameterName,
object value)
{
IDbDataParameter parameter = _dataProvider.CreateParameterObject(Command);
parameter.ParameterName = parameterName;
parameter.Direction = parameterDirection;
//_dataProvider.SetParameterType(parameter, value);
parameter.Value = value ?? DBNull.Value;
return parameter;
}
///
/// Adds a parameter to the .
///
///
/// The method creates a parameter with the specified
/// type.
///
/// One of the values.
/// The name of the parameter.
/// The
/// that is the value of the parameter.
/// One of the values.
/// The object.
public IDbDataParameter Parameter(
ParameterDirection parameterDirection,
string parameterName,
object value,
DbType dbType)
{
IDbDataParameter parameter = _dataProvider.CreateParameterObject(Command);
parameter.ParameterName = parameterName;
parameter.Direction = parameterDirection;
parameter.DbType = dbType;
parameter.Value = value;
return parameter;
}
///
/// Adds an input parameter to the .
///
/// The name of the parameter.
/// The
/// that is the value of the parameter.
/// One of the values.
/// The object.
public IDbDataParameter Parameter(
string parameterName,
object value,
DbType dbType)
{
return Parameter(ParameterDirection.Input, parameterName, value, dbType);
}
///
/// Adds a parameter to the .
///
///
/// The method creates a parameter with the specified
/// type.
///
/// One of the values.
/// The name of the parameter.
/// The
/// that is the value of the parameter.
/// One of the values.
/// Size of the parameter.
/// The object.
public IDbDataParameter Parameter(
ParameterDirection parameterDirection,
string parameterName,
object value,
DbType dbType,
int size)
{
IDbDataParameter parameter = _dataProvider.CreateParameterObject(Command);
parameter.ParameterName = parameterName;
parameter.Direction = parameterDirection;
parameter.DbType = dbType;
parameter.Size = size;
parameter.Value = value;
return parameter;
}
///
/// Adds a parameter to the .
///
///
/// The method creates a parameter with the specified
/// type.
///
/// One of the values.
/// The name of the parameter.
/// The
/// that is the value of the parameter.
/// User defined type name for a table-valued parameter.
/// The object.
public IDbDataParameter Parameter(
ParameterDirection parameterDirection,
string parameterName,
object value,
string typeName)
{
IDbDataParameter parameter = _dataProvider.CreateParameterObject(Command);
parameter.ParameterName = parameterName;
parameter.Direction = parameterDirection;
_dataProvider.SetUserDefinedType(parameter, typeName);
parameter.Value = value;
return parameter;
}
///
/// Adds an input parameter to the .
///
/// The name of the parameter.
/// The
/// that is the value of the parameter.
/// One of the values.
/// Size of the parameter.
/// The object.
public IDbDataParameter Parameter(
string parameterName,
object value,
DbType dbType,
int size)
{
return Parameter(ParameterDirection.Input, parameterName, value, dbType, size);
}
///
/// Adds a parameter to the .
///
///
/// The method creates a parameter with the specified
/// type.
///
/// One of the values.
/// The name of the parameter.
/// One of the values.
/// The object.
public IDbDataParameter Parameter(
ParameterDirection parameterDirection,
string parameterName,
DbType dbType)
{
IDbDataParameter parameter = _dataProvider.CreateParameterObject(Command);
parameter.ParameterName = parameterName;
parameter.Direction = parameterDirection;
parameter.DbType = dbType;
return parameter;
}
///
/// Adds a parameter to the .
///
///
/// The method creates a parameter with the specified
/// type.
///
/// One of the values.
/// The name of the parameter.
/// One of the values.
/// Size of the parameter.
/// The object.
public IDbDataParameter Parameter(
ParameterDirection parameterDirection,
string parameterName,
DbType dbType,
int size)
{
IDbDataParameter parameter = _dataProvider.CreateParameterObject(Command);
parameter.ParameterName = parameterName;
parameter.Direction = parameterDirection;
parameter.DbType = dbType;
parameter.Size = size;
return parameter;
}
///
/// Creates an input parameter to the .
///
///
/// The method creates a parameter with the
/// ParameterDirection.Input type
/// and DataRowVersion.Current type.
///
/// The name of the parameter.
/// One of the values.
/// Size of the parameter.
/// Source column for a parameter in the .
/// The object.
public IDbDataParameter Parameter(
string parameterName,
DbType dbType,
int size,
string sourceColumn)
{
IDbDataParameter param = Parameter(ParameterDirection.Input, parameterName, dbType, size);
param.SourceColumn = sourceColumn;
param.SourceVersion = DataRowVersion.Current;
return param;
}
///
/// Creates an input parameter to the .
///
///
/// The method creates a parameter with the
/// ParameterDirection.Input type
/// and DataRowVersion.Current type.
///
/// The name of the parameter.
/// One of the values.
/// Source column for a parameter in the .
/// The object.
public IDbDataParameter Parameter(
string parameterName,
DbType dbType,
string sourceColumn)
{
IDbDataParameter param = Parameter(ParameterDirection.Input, parameterName, dbType);
param.SourceColumn = sourceColumn;
param.SourceVersion = DataRowVersion.Current;
return param;
}
///
/// Creates an input parameter to the .
///
///
/// The method creates a parameter with the
/// ParameterDirection.Input type
/// and DataRowVersion.Current type.
///
/// The name of the parameter.
/// One of the values.
/// Size of the parameter.
/// Source column for a parameter in the .
/// Version of data to use for a parameter in the .
/// The object.
public IDbDataParameter Parameter(
string parameterName,
DbType dbType,
int size,
string sourceColumn,
DataRowVersion dataRowVersion)
{
IDbDataParameter param = Parameter(ParameterDirection.Input, parameterName, dbType, size);
param.SourceColumn = sourceColumn;
param.SourceVersion = dataRowVersion;
return param;
}
///
/// Creates an input parameter to the .
///
///
/// The method creates a parameter with the
/// ParameterDirection.Input type
/// and DataRowVersion.Current type.
///
/// The name of the parameter.
/// One of the values.
/// Source column for a parameter in the .
/// Version of data to use for a parameter in the .
/// The object.
public IDbDataParameter Parameter(
string parameterName,
DbType dbType,
string sourceColumn,
DataRowVersion dataRowVersion)
{
IDbDataParameter param = Parameter(ParameterDirection.Input, parameterName, dbType);
param.SourceColumn = sourceColumn;
param.SourceVersion = dataRowVersion;
return param;
}
#endregion
#region SetCommand
///
/// Specifies the action that command is supposed to perform, i.e. Select, Insert, Update, Delete.
/// It is used in Execute methods of the class to identify command instance
/// to be used.
///
enum CommandAction
{
Select,
Insert,
Update,
Delete
}
private bool _executed;
private bool _prepared;
private IDbDataParameter[] _selectCommandParameters;
private IDbDataParameter[] _insertCommandParameters;
private IDbDataParameter[] _updateCommandParameters;
private IDbDataParameter[] _deleteCommandParameters;
private void SetCommand(CommandAction commandAction, IDbCommand command)
{
switch (commandAction)
{
case CommandAction.Select: _selectCommand = command; break;
case CommandAction.Insert: _insertCommand = command; break;
case CommandAction.Update: _updateCommand = command; break;
case CommandAction.Delete: _deleteCommand = command; break;
}
}
private IDbCommand GetCommand(CommandAction commandAction)
{
switch (commandAction)
{
default:
case CommandAction.Select: return SelectCommand;
case CommandAction.Insert: return InsertCommand;
case CommandAction.Update: return UpdateCommand;
case CommandAction.Delete: return DeleteCommand;
}
}
private void SetCommandParameters(CommandAction commandAction, IDbDataParameter[] commandParameters)
{
switch (commandAction)
{
case CommandAction.Select: _selectCommandParameters = commandParameters; break;
case CommandAction.Insert: _insertCommandParameters = commandParameters; break;
case CommandAction.Update: _updateCommandParameters = commandParameters; break;
case CommandAction.Delete: _deleteCommandParameters = commandParameters; break;
}
}
private IDbDataParameter[] GetCommandParameters(CommandAction commandAction)
{
switch (commandAction)
{
default:
case CommandAction.Select: return _selectCommandParameters;
case CommandAction.Insert: return _insertCommandParameters;
case CommandAction.Update: return _updateCommandParameters;
case CommandAction.Delete: return _deleteCommandParameters;
}
}
private DbManager SetCommand(
CommandAction commandAction,
CommandType commandType,
string commandText,
params IDbDataParameter[] commandParameters)
{
if (_executed)
{
_executed = false;
_prepared = false;
}
PrepareCommand(commandAction, commandType, commandText, commandParameters);
return this;
}
private DbManager SetSpCommand(
CommandAction commandAction,
string spName,
bool openNewConnectionToDiscoverParameters,
params object[] parameterValues)
{
return SetCommand(
commandAction,
CommandType.StoredProcedure,
spName,
CreateSpParameters(spName, parameterValues, openNewConnectionToDiscoverParameters));
}
private DbManager SetSpCommand(
CommandAction commandAction,
string spName,
params object[] parameterValues)
{
return SetCommand(
commandAction,
CommandType.StoredProcedure,
spName,
CreateSpParameters(spName, parameterValues, Configuration.OpenNewConnectionToDiscoverParameters));
}
#region Select
///
/// Creates a SQL statement.
///
/// The command text to execute.
/// Current instance.
public DbManager SetCommand(
string commandText)
{
return SetCommand(CommandAction.Select, CommandType.Text, commandText, null);
}
///
/// Creates a SQL statement.
///
/// The (stored procedure, text, etc.)
/// The command text to execute.
/// Current instance.
public DbManager SetCommand(
CommandType commandType,
string commandText)
{
return SetCommand(CommandAction.Select, commandType, commandText, null);
}
///
/// Creates a SQL statement.
///
///
/// The method can be used to create the INSERT, UPDATE, and DELETE SQL statements.
///
/// The command text to execute.
/// An array of parameters used to executes the command.
/// Current instance.
public DbManager SetCommand(
string commandText,
params IDbDataParameter[] commandParameters)
{
return SetCommand(CommandAction.Select, CommandType.Text, commandText, commandParameters);
}
///
/// Creates a SQL statement.
///
/// The (stored procedure, text, etc.)
/// The command text to execute.
/// An array of parameters used to executes the command.
/// Current instance.
public DbManager SetCommand(
CommandType commandType,
string commandText,
params IDbDataParameter[] commandParameters)
{
return SetCommand(CommandAction.Select, commandType, commandText, commandParameters);
}
///
/// Creates a command to be executed as a stored procedure using the provided parameter values.
///
///
/// The method queries the database to discover the parameters for the stored procedure
/// (the first time each stored procedure is called),
/// and assign the values based on parameter order.
///
/// The name of the stored procedure
/// An array of objects to be assigned as the input values of the stored procedure
/// Current instance.
public DbManager SetSpCommand(
string spName,
params object[] parameterValues)
{
return SetSpCommand(CommandAction.Select, spName, parameterValues);
}
public DbManager SetSpCommand(
string spName,
bool openNewConnectionToDiscoverParameters,
params object[] parameterValues)
{
return SetSpCommand(CommandAction.Select, spName, openNewConnectionToDiscoverParameters, parameterValues);
}
public DbManager SetCommand(SqlQuery sql, params IDbDataParameter[] commandParameters)
{
StringBuilder sb = new StringBuilder();
DataProvider.CreateSqlProvider().BuildSql(sql, sb, 0, 0);
string command = sb.ToString();
#if DEBUG
string info = string.Format("{0} {1}\n{2}", DataProvider.Name, ConfigurationString, command);
if (commandParameters != null && commandParameters.Length > 0)
foreach (IDbDataParameter p in commandParameters)
info += string.Format("\n{0}\t{1}", p.ParameterName, p.Value);
Debug.WriteLineIf(TraceSwitch.TraceInfo, info, TraceSwitch.DisplayName);
#endif
return SetCommand(command, commandParameters);
}
#endregion
#region Insert
///
/// Creates an Insert SQL statement.
///
///
/// The method can be used to create the INSERT, UPDATE, and DELETE SQL statements.
///
/// The command text to execute.
/// An array of parameters used to executes the command.
/// Current instance.
public DbManager SetInsertCommand(
string commandText,
params IDbDataParameter[] commandParameters)
{
return SetCommand(
CommandAction.Insert, CommandType.Text, commandText, commandParameters);
}
///
/// Creates an Insert SQL statement.
///
/// The (stored procedure, text, etc.)
/// The command text to execute.
/// An array of parameters used to executes the command.
/// Current instance.
public DbManager SetInsertCommand(
CommandType commandType,
string commandText,
params IDbDataParameter[] commandParameters)
{
return SetCommand(
CommandAction.Insert, commandType, commandText, commandParameters);
}
///
/// Creates an Insert command to be executed as a stored procedure using the provided parameter values.
///
///
/// The method queries the database to discover the parameters for the stored procedure
/// (the first time each stored procedure is called),
/// and assign the values based on parameter order.
///
/// The name of the stored procedure
/// An array of objects to be assigned as the input values of the stored procedure
/// Current instance.
public DbManager SetInsertSpCommand(
string spName,
params object[] parameterValues)
{
return SetSpCommand(CommandAction.Insert, spName, parameterValues);
}
#endregion
#region Update
///
/// Creates an Update SQL statement.
///
///
/// The method can be used to create the INSERT, UPDATE, and DELETE SQL statements.
///
/// The command text to execute.
/// An array of parameters used to executes the command.
/// Current instance.
public DbManager SetUpdateCommand(
string commandText,
params IDbDataParameter[] commandParameters)
{
return SetCommand(
CommandAction.Update, CommandType.Text, commandText, commandParameters);
}
///
/// Creates an Update SQL statement.
///
/// The (stored procedure, text, etc.)
/// The command text to execute.
/// An array of parameters used to executes the command.
/// Current instance.
public DbManager SetUpdateCommand(
CommandType commandType,
string commandText,
params IDbDataParameter[] commandParameters)
{
return SetCommand(
CommandAction.Update, commandType, commandText, commandParameters);
}
///
/// Creates an Update command to be executed as a stored procedure using the provided parameter values.
///
///
/// The method queries the database to discover the parameters for the stored procedure
/// (the first time each stored procedure is called),
/// and assign the values based on parameter order.
///
/// The name of the stored procedure
/// An array of objects to be assigned as the input values of the stored procedure
/// Current instance.
public DbManager SetUpdateSpCommand(
string spName,
params object[] parameterValues)
{
return SetSpCommand(CommandAction.Update, spName, parameterValues);
}
#endregion
#region Delete
///
/// Creates a Delete SQL statement.
///
///
/// The method can be used to create the INSERT, UPDATE, and DELETE SQL statements.
///
/// The command text to execute.
/// An array of parameters used to executes the command.
/// Current instance.
public DbManager SetDeleteCommand(
string commandText,
params IDbDataParameter[] commandParameters)
{
return SetCommand(
CommandAction.Delete, CommandType.Text, commandText, commandParameters);
}
///
/// Creates a Delete SQL statement.
///
/// The (stored procedure, text, etc.)
/// The command text to execute.
/// An array of parameters used to executes the command.
/// Current instance.
public DbManager SetDeleteCommand(
CommandType commandType,
string commandText,
params IDbDataParameter[] commandParameters)
{
return SetCommand(
CommandAction.Delete, commandType, commandText, commandParameters);
}
///
/// Creates a Delete command to be executed as a stored procedure using the provided parameter values.
///
///
/// The method queries the database to discover the parameters for the stored procedure
/// (the first time each stored procedure is called),
/// and assign the values based on parameter order.
///
/// The name of the stored procedure
/// An array of objects to be assigned as the input values of the stored procedure
/// Current instance.
public DbManager SetDeleteSpCommand(
string spName,
params object[] parameterValues)
{
return SetSpCommand(CommandAction.Delete, spName, parameterValues);
}
#endregion
#endregion
#region Prepare
private void PrepareCommand(
CommandAction commandAction,
CommandType commandType,
string commandText,
IDbDataParameter[] commandParameters)
{
DataProvider.PrepareCommand(ref commandType, ref commandText, ref commandParameters);
IDbCommand command = GetCommand(commandAction, commandType, commandText);
SetCommand (commandAction, command);
SetCommandParameters(commandAction, commandParameters);
if (commandParameters != null)
{
AttachParameters(command, commandParameters);
}
}
///
/// Prepares a command for execution.
///
/// Current instance.
public DbManager Prepare()
{
IDbCommand command = GetCommand(CommandAction.Select);
if (InitParameters(CommandAction.Select) == false)
{
ExecuteOperation(OperationType.PrepareCommand, command.Prepare);
}
_prepared = true;
return this;
}
bool InitParameters(CommandAction commandAction)
{
bool prepare = false;
IDbDataParameter[] commandParameters = GetCommandParameters(commandAction);
if (commandParameters != null)
{
foreach (IDbDataParameter p in commandParameters)
{
// This mysterious line of code required to fix a bug in MsSql.
// It forces parameter's filed 'MetaType' to be set.
// Same for p.Size = p.Size below.
//
p.DbType = p.DbType;
if (p.Value is string)
{
int len = ((string)p.Value).Length;
if (p.Size < len)
{
p.Size = len;
prepare = true;
}
else
p.Size = p.Size;
}
else if (p.Value is DBNull)
{
p.Size = 1;
}
else if (p.Value is byte[])
{
int len = ((byte[])p.Value).Length;
if (p.Size < len)
{
p.Size = len;
prepare = true;
}
else
p.Size = p.Size;
}
else if (p.Value is char[])
{
int len = ((char[])p.Value).Length;
if (p.Size < len)
{
p.Size = len;
prepare = true;
}
else
p.Size = p.Size;
}
else if (p.Value is decimal)
{
SqlDecimal d = (decimal)p.Value;
if (p.Precision < d.Precision)
{
p.Precision = d.Precision;
prepare = true;
}
else
p.Precision = p.Precision;
if (p.Scale < d.Scale)
{
p.Scale = d.Scale;
prepare = true;
}
else
p.Scale = p.Scale;
}
}
// Re-prepare command to avoid truncation.
//
if (prepare)
{
IDbCommand command = GetCommand(commandAction);
AttachParameters(command, commandParameters);
command.Prepare();
}
}
return prepare;
}
#endregion
#region ExecuteForEach
///
/// Executes a SQL statement for a given collection of objects and
/// returns the number of rows affected.
///
///
/// The method prepares the object
/// and calls the method for each item of the list.
///
///
/// The list of objects used to execute the command.
/// The number of rows affected by the command.
public int ExecuteForEach(ICollection collection)
{
int rowsTotal = 0;
if (collection != null && collection.Count != 0)
{
bool initParameters = true;
foreach (object o in collection)
{
if (initParameters)
{
initParameters = false;
IDbDataParameter[] parameters = GetCommandParameters(CommandAction.Select);
if (parameters == null || parameters.Length == 0)
{
parameters = CreateParameters(o);
SetCommandParameters(CommandAction.Select, parameters);
AttachParameters(SelectCommand, parameters);
Prepare();
}
}
AssignParameterValues(o);
int rows = ExecuteNonQueryInternal();
if (rows > 0)
rowsTotal += rows;
}
}
return rowsTotal;
}
///
/// Executes a SQL statement for a given collection of objects and
/// returns the number of rows affected.
///
///
/// The method prepares the object
/// and calls the method for each item of the list.
///
///
/// The list of objects used to execute the command.
/// The number of rows affected by the command.
public int ExecuteForEach(ICollection collection)
{
int rowsTotal = 0;
if (collection != null && collection.Count != 0)
{
bool initParameters = true;
foreach (T o in collection)
{
if (initParameters)
{
initParameters = false;
IDbDataParameter[] parameters = GetCommandParameters(CommandAction.Select);
if (parameters == null || parameters.Length == 0)
{
parameters = CreateParameters(o);
SetCommandParameters(CommandAction.Select, parameters);
AttachParameters(SelectCommand, parameters);
Prepare();
}
}
AssignParameterValues(o);
int rows = ExecuteNonQueryInternal();
if (rows > 0)
rowsTotal += rows;
}
}
return rowsTotal;
}
public int ExecuteForEach(int maxBatchSize, IEnumerable collection)
{
ObjectMapper om = _mappingSchema.GetObjectMapper(typeof(T));
List mms = new List();
foreach (MemberMapper mm in om)
{
string name = _dataProvider.Convert(mm.Name, ConvertType.NameToParameter).ToString();
if (Command.Parameters.Contains(name))
mms.Add(mm);
}
return ExecuteForEach(collection, mms.ToArray(), maxBatchSize, delegate(T obj) { return CreateParameters(obj); });
}
public delegate IDbDataParameter[] ParameterProvider(T obj);
internal int ExecuteForEach(IEnumerable collection, MemberMapper[] members, int maxBatchSize, ParameterProvider getParameters)
{
if (collection == null)
return 0;
int maxRows =
Math.Max(
Math.Min(
Math.Max(
members.Length == 0? 1000 : _dataProvider.MaxParameters / members.Length,
members.Length),
maxBatchSize),
1);
string baseSql = SelectCommand.CommandText;
string paramName = _dataProvider.Convert(".", ConvertType.NameToQueryParameter).ToString();
int rowsTotal = 0;
int nRows = 0;
bool initParameters = true;
bool saveCanRaseEvent = _canRaiseEvents;
_canRaiseEvents = false;
StringBuilder sb = new StringBuilder();
List rowSql = new List(maxRows);
IDbDataParameter[] baseParameters = null;
List parameters = new List();
foreach (T obj in collection)
{
if (initParameters)
{
initParameters = false;
baseParameters = getParameters(obj);
if (maxRows != 1)
{
int n = 0;
foreach (IDbDataParameter p in baseParameters)
n += p.ParameterName.Length + 3 - "{0}".Length + _dataProvider.EndOfSql.Length;
maxRows = Math.Max(1, Math.Min(maxRows, _dataProvider.MaxBatchSize / (baseSql.Length + n)));
}
if (maxRows != 1)
baseSql += _dataProvider.EndOfSql;
}
bool isSet;
if (rowSql.Count < maxRows)
{
isSet = false;
Converter c1 = delegate(IDbDataParameter p) { return p.ParameterName + nRows; };
Converter c2 = delegate(IDbDataParameter p) { return p.ParameterName; };
sb
.Append("\n")
.AppendFormat(
baseSql,
Array.ConvertAll(
baseParameters,
baseParameters.Length > 0 && baseParameters[0].ParameterName != paramName? c1 : c2));
rowSql.Add(sb.Length);
for (int i = 0; i < members.Length; i++)
{
object value = members[i].GetValue(obj);
parameters.Add(Parameter(baseParameters[i].ParameterName + nRows, value ?? DBNull.Value));
}
}
else
{
isSet = true;
for (int i = 0, n = nRows * members.Length; i < members.Length; i++)
{
object value = members[i].GetValue(obj);
parameters[n + i].Value =
value == null || members[i].MapMemberInfo.Nullable && _mappingSchema.IsNull(value)?
DBNull.Value: value;
}
}
nRows++;
if (nRows >= maxRows)
{
if (isSet == false)
{
SetCommand(sb.ToString(), parameters.ToArray());
Prepare();
}
else
{
InitParameters(CommandAction.Select);
}
int n = ExecuteNonQueryInternal();
if (n > 0)
rowsTotal += n;
nRows = 0;
}
}
if (nRows > 0)
{
if (rowSql.Count >= maxRows)
{
int nps = nRows * members.Length;
parameters.RemoveRange(nps, parameters.Count - nps);
sb.Length = rowSql[nRows - 1];
}
SetCommand(sb.ToString(), parameters.ToArray());
Prepare();
int n = ExecuteNonQueryInternal();
if (n > 0)
rowsTotal += n;
}
_canRaiseEvents = saveCanRaseEvent;
return rowsTotal;
}
///
/// Executes a SQL statement for the and
/// returns the number of rows affected.
///
///
/// The method prepares the object
/// and calls the method for each item
/// of the .
///
///
/// An instance of the class to execute the command.
/// The number of rows affected by the command.
public int ExecuteForEach(DataTable table)
{
int rowsTotal = 0;
if (table != null && table.Rows.Count != 0)
{
IDbDataParameter[] parameters = GetCommandParameters(CommandAction.Select);
if (parameters == null || parameters.Length == 0)
{
parameters = CreateParameters(table.Rows[0]);
SetCommandParameters(CommandAction.Select, parameters);
AttachParameters(SelectCommand, parameters);
Prepare();
}
foreach (DataRow dr in table.Rows)
{
AssignParameterValues(dr);
int rows = ExecuteNonQueryInternal();
if (rows > 0)
rowsTotal += rows;
}
}
return rowsTotal;
}
///
/// Executes a SQL statement for the first table of the
/// and returns the number of rows affected.
///
///
/// The method prepares the object
/// and calls the method for each item of the first table.
///
///
/// An instance of the class to execute the command.
/// The number of rows affected by the command.
public int ExecuteForEach(DataSet dataSet)
{
return ExecuteForEach(dataSet.Tables[0]);
}
///
/// Executes a SQL statement for the specified table of the
/// and returns the number of rows affected.
///
///
/// The method prepares the object
/// and calls the method for each item of the first table.
///
///
/// An instance of the class to execute the command.
/// The table name or index.
/// name/index.
/// The number of rows affected by the command.
public int ExecuteForEach(DataSet dataSet, NameOrIndexParameter nameOrIndex)
{
return nameOrIndex.ByName ? ExecuteForEach(dataSet.Tables[nameOrIndex.Name])
: ExecuteForEach(dataSet.Tables[nameOrIndex.Index]);
}
#endregion
#region ExecuteNonQuery
///
/// Executes a SQL statement and returns the number of rows affected.
///
///
/// The method can be used to execute the INSERT, UPDATE, and DELETE SQL statements.
///
///
/// The number of rows affected by the command.
public int ExecuteNonQuery()
{
if (_prepared)
InitParameters(CommandAction.Select);
return ExecuteNonQueryInternal();
}
///
/// Executes a SQL statement and returns the number of rows affected.
///
///
/// The method can be used to execute the INSERT, UPDATE, and DELETE SQL statements.
///
/// Name of a to map return value.
/// An to map from command parameters.
/// The number of rows affected by the command.
public int ExecuteNonQuery(
string returnValueMember,
object obj)
{
int rowsAffected = ExecuteNonQuery();
MapOutputParameters(returnValueMember, obj);
return rowsAffected;
}
///
/// Executes a SQL statement and returns the number of rows affected.
///
///
/// The method can be used to execute the INSERT, UPDATE, and DELETE SQL statements.
///
/// An to map from command parameters.
/// The number of rows affected by the command.
public int ExecuteNonQuery(object obj)
{
int rowsAffected = ExecuteNonQuery();
MapOutputParameters(null, obj);
return rowsAffected;
}
///
/// Executes a SQL statement and returns the number of rows affected.
///
///
/// The method can be used to execute the INSERT, UPDATE, and DELETE SQL statements.
///
/// Name of a to map return value.
/// An array of to map
/// from command parameters.
/// The number of rows affected by the command.
public int ExecuteNonQuery(
string returnValueMember,
params object[] objects)
{
int rowsAffected = ExecuteNonQuery();
MapOutputParameters(returnValueMember, objects);
return rowsAffected;
}
///
/// Executes a SQL statement and returns the number of rows affected.
///
///
/// The method can be used to execute the INSERT, UPDATE, and DELETE SQL statements.
///
/// An array of to map
/// from command parameters.
/// The number of rows affected by the command.
public int ExecuteNonQuery(params object[] objects)
{
int rowsAffected = ExecuteNonQuery();
MapOutputParameters(null, objects);
return rowsAffected;
}
#endregion
#region ExecuteScalar
///
/// Executes the query, and returns the first column of the first row
/// in the resultset returned by the query. Extra columns or rows are
/// ignored.
///
/// The first column of the first row in the resultset.
///
public object ExecuteScalar()
{
if (_prepared)
InitParameters(CommandAction.Select);
using (IDataReader rd = ExecuteReaderInternal(CommandBehavior.Default))
return rd.Read() && rd.FieldCount > 0 ? rd.GetValue(0) : null;
}
///
/// Executes the query, and returns the value with specified scalar
/// source type.
///
/// The method used to return the scalar
/// value.
///
///
/// ScalarSourceType
/// Return value
///
/// -
/// DataReader
/// The first column of the first row in the resultset.
///
///
/// -
/// OutputParameter
/// The value of the first output or input/output
/// parameter returned.
///
/// -
/// ReturnValue
/// The value of the "return value" parameter returned.
///
///
/// -
/// AffectedRows
/// The number of rows affected.
///
///
///
///
public object ExecuteScalar(ScalarSourceType sourceType)
{
return ExecuteScalar(sourceType, new NameOrIndexParameter());
}
///
/// Executes the query, and returns the value with specified scalar
/// source type.
///
/// The method used to return the scalar value.
/// The column name/index or output parameter name/index.
///
///
/// ScalarSourceType
/// Return value
///
/// -
/// DataReader
/// The column with specified name or at specified index
/// of the first row in the resultset.
///
/// -
/// OutputParameter
/// The value of the output or input/output parameter
/// returned with specified name or at specified index.
///
/// -
/// ReturnValue
/// The value of the "return value" parameter returned.
/// The index parameter is ignored.
///
/// -
/// AffectedRows
/// The number of rows affected. The index parameter is
/// ignored.
///
///
///
public object ExecuteScalar(ScalarSourceType sourceType, NameOrIndexParameter nameOrIndex)
{
if (_prepared)
InitParameters(CommandAction.Select);
switch (sourceType)
{
case ScalarSourceType.DataReader:
using (IDataReader reader = ExecuteReaderInternal())
if (reader.Read())
return reader.GetValue(nameOrIndex.ByName ? reader.GetOrdinal(nameOrIndex.Name) : nameOrIndex.Index);
break;
case ScalarSourceType.OutputParameter:
ExecuteNonQueryInternal();
if (nameOrIndex.ByName)
{
string name = (string)_dataProvider.Convert(nameOrIndex.Name,
ConvertType.NameToParameter);
return Parameter(name).Value;
}
int index = nameOrIndex.Index;
foreach (IDataParameter p in SelectCommand.Parameters)
{
// Skip the return value parameter.
//
if (p.Direction == ParameterDirection.ReturnValue)
continue;
if (0 == index)
return p.Value;
--index;
}
break;
case ScalarSourceType.ReturnValue:
ExecuteNonQueryInternal();
foreach (IDataParameter p in SelectCommand.Parameters)
if (p.Direction == ParameterDirection.ReturnValue)
return p.Value;
break;
case ScalarSourceType.AffectedRows:
return ExecuteNonQueryInternal();
default:
throw new InvalidEnumArgumentException("sourceType",
(int)sourceType, typeof(ScalarSourceType));
}
return null;
}
///
/// Executes the query, and returns the first column of the first row
/// in the resultset returned by the query. Extra columns or rows are
/// ignored.
///
///
/// The first column of the first row in the resultset.
///
public T ExecuteScalar()
{
return (T)_mappingSchema.ConvertChangeType(ExecuteScalar(), typeof(T));
}
///
/// Executes the query, and returns the value with specified scalar
/// source type.
///
/// The method used to return the scalar
/// value.
///
///
/// ScalarSourceType
/// Return value
///
/// -
/// DataReader
/// The first column of the first row in the resultset.
///
///
/// -
/// OutputParameter
/// The value of the first output or input/output
/// parameter returned.
///
/// -
/// ReturnValue
/// The value of the "return value" parameter returned.
///
///
/// -
/// AffectedRows
/// The number of rows affected.
///
///
///
///
public T ExecuteScalar(ScalarSourceType sourceType)
{
return ExecuteScalar(sourceType, new NameOrIndexParameter());
}
///
/// Executes the query, and returns the value with specified scalar
/// source type.
///
/// The method used to return the scalar value.
/// The column name/index or output parameter name/index.
///
///
/// ScalarSourceType
/// Return value
///
/// -
/// DataReader
/// The column with specified name or at specified index
/// of the first row in the resultset.
///
/// -
/// OutputParameter
/// The value of the output or input/output parameter
/// returned with specified name or at specified index.
///
/// -
/// ReturnValue
/// The value of the "return value" parameter returned.
/// The index parameter is ignored.
///
/// -
/// AffectedRows
/// The number of rows affected. The index parameter is
/// ignored.
///
///
///
public T ExecuteScalar(ScalarSourceType sourceType, NameOrIndexParameter nameOrIndex)
{
return (T)_mappingSchema.ConvertChangeType(ExecuteScalar(sourceType, nameOrIndex), typeof(T));
}
#endregion
#region ExecuteScalarList
///
/// Executes the query, and returns the array list of values of the
/// specified column of the every row in the resultset returned by the
/// query. Other columns are ignored.
///
/// The array to fill in.
/// The column name/index or output parameter name/index.
/// The type of the each element.
/// Array list of values of the specified column of the every
/// row in the resultset.
public IList ExecuteScalarList(
IList list,
Type type,
NameOrIndexParameter nameOrIndex)
{
if (list == null)
list = new ArrayList();
if (_prepared)
InitParameters(CommandAction.Select);
using (IDataReader dr = ExecuteReaderInternal())
{
return _mappingSchema.MapDataReaderToScalarList(dr, nameOrIndex, list, type);
}
}
///
/// Executes the query, and returns the array list of values of first
/// column of the every row in the resultset returned by the query.
/// Other columns are ignored.
///
/// The array to fill in.
/// The type of the each element.
/// Array list of values of first column of the every row in
/// the resultset.
public IList ExecuteScalarList(IList list, Type type)
{
if (list == null)
list = new ArrayList();
return ExecuteScalarList(list, type, 0);
}
///
/// Executes the query, and returns the array list of values of the
/// specified column of the every row in the resultset returned by the
/// query. Other columns are ignored.
///
/// The column name/index.
/// The type of the each element.
/// Array list of values of the specified column of the every
/// row in the resultset.
public ArrayList ExecuteScalarList(Type type, NameOrIndexParameter nameOrIndex)
{
ArrayList list = new ArrayList();
ExecuteScalarList(list, type, nameOrIndex);
return list;
}
///
/// Executes the query, and returns the array list of values of first
/// column of the every row in the resultset returned by the query.
/// Other columns are ignored.
///
/// The type of the each element.
/// Array list of values of first column of the every row in
/// the resultset.
public ArrayList ExecuteScalarList(Type type)
{
ArrayList list = new ArrayList();
ExecuteScalarList(list, type, 0);
return list;
}
///
/// Executes the query, and returns the array list of values of the
/// specified column of the every row in the resultset returned by the
/// query. Other columns are ignored.
///
/// The array to fill in.
/// The column name/index or output parameter
/// name/index.
/// The type of the each element.
/// Array list of values of the specified column of the every
/// row in the resultset.
public IList ExecuteScalarList(
IList list,
NameOrIndexParameter nameOrIndex)
{
if (list == null)
list = new List();
if (_prepared)
InitParameters(CommandAction.Select);
using (IDataReader dr = ExecuteReaderInternal())
{
return _mappingSchema.MapDataReaderToScalarList(dr, nameOrIndex, list);
}
}
///
/// Executes the query, and returns the array list of values of first
/// column of the every row in the resultset returned by the query.
/// Other columns are ignored.
///
/// The array to fill in.
/// The type of the each element.
/// Array list of values of first column of the every row in
/// the resultset.
public IList ExecuteScalarList(IList list)
{
return ExecuteScalarList(list, 0);
}
///
/// Executes the query, and returns the array list of values of the
/// specified column of the every row in the resultset returned by the
/// query. Other columns are ignored.
///
/// The column name/index or output parameter name/index.
/// The type of the each element.
/// Array list of values of the specified column of the every
/// row in the resultset.
public List ExecuteScalarList(NameOrIndexParameter nameOrIndex)
{
List list = new List();
ExecuteScalarList(list, nameOrIndex);
return list;
}
///
/// Executes the query, and returns the list of values of first
/// column of the every row in the resultset returned by the query.
/// Other columns are ignored.
///
/// The type of the each element.
/// Array list of values of first column of the every row in
/// the resultset.
public List ExecuteScalarList()
{
List list = new List();
ExecuteScalarList(list, 0);
return list;
}
#endregion
#region ExecuteScalarDictionary
///
/// Executes the query, and returns the dictionary.
/// The keys are loaded from a column specified by and
/// values are loaded from a column specified by .
/// Other columns are ignored.
///
///The dictionary to add values.
///The column name/index to load keys.
///The key type.
///The column name/index to load values.
///The value type.
///The loaded dictionary.
public IDictionary ExecuteScalarDictionary(
IDictionary dic,
NameOrIndexParameter keyField, Type keyFieldType,
NameOrIndexParameter valueField, Type valueFieldType)
{
if (dic == null)
dic = new Hashtable();
if (_prepared)
InitParameters(CommandAction.Select);
//object nullValue = _mappingSchema.GetNullValue(type);
if (keyField.ByName && keyField.Name.Length > 0 && keyField.Name[0] == '@')
keyField = keyField.Name.Substring(1);
using (IDataReader dr = ExecuteReaderInternal())
{
if (dr.Read())
{
int keyIndex = keyField.ByName ? dr.GetOrdinal(keyField.Name) : keyField.Index;
int valueIndex = valueField.ByName ? dr.GetOrdinal(valueField.Name) : valueField.Index;
do
{
object value = dr[valueIndex];
object key = dr[keyIndex];
if (key == null || key.GetType() != keyFieldType)
key = key is DBNull ? null : _mappingSchema.ConvertChangeType(key, keyFieldType);
if (value == null || value.GetType() != valueFieldType)
value = value is DBNull ? null : _mappingSchema.ConvertChangeType(value, valueFieldType);
dic.Add(key, value);
}
while (dr.Read());
}
}
return dic;
}
///
/// Executes the query, and returns the dictionary.
/// The keys are loaded from a column specified by and
/// values are loaded from a column specified by .
/// Other columns are ignored.
///
///The column name/index to load keys.
///The key type.
///The column name/index to load values.
///The value type.
///The loaded dictionary.
public Hashtable ExecuteScalarDictionary(
NameOrIndexParameter keyField, Type keyFieldType,
NameOrIndexParameter valueField, Type valueFieldType)
{
Hashtable table = new Hashtable();
ExecuteScalarDictionary(table, keyField, keyFieldType, valueField, valueFieldType);
return table;
}
///
/// Executes the query, and returns the dictionary.
/// The keys are loaded from a column specified by and
/// values are loaded from a column specified by .
/// Other columns are ignored.
///
///The key type.
///The value type.
///The dictionary to add values.
///The column name/index to load keys.
///The column name/index to load values.
///The loaded dictionary.
public IDictionary ExecuteScalarDictionary(
IDictionary dic,
NameOrIndexParameter keyField,
NameOrIndexParameter valueField)
{
if (dic == null)
dic = new Dictionary();
if (_prepared)
InitParameters(CommandAction.Select);
//object nullValue = _mappingSchema.GetNullValue(type);
Type keyFieldType = typeof(K);
Type valueFieldType = typeof(T);
using (IDataReader dr = ExecuteReaderInternal())
{
if (dr.Read())
{
int keyIndex = keyField.ByName? dr.GetOrdinal(keyField.Name): keyField.Index;
int valueIndex = valueField.ByName? dr.GetOrdinal(valueField.Name): valueField.Index;
do
{
object value = dr[valueIndex];
object key = dr[keyIndex];
if (key == null || key.GetType() != keyFieldType)
key = key is DBNull ? null : _mappingSchema.ConvertChangeType(key, keyFieldType);
if (value == null || value.GetType() != valueFieldType)
value = value is DBNull ? null : _mappingSchema.ConvertChangeType(value, valueFieldType);
dic.Add((K)key, (T)value);
}
while (dr.Read());
}
}
return dic;
}
///
/// Executes the query, and returns the dictionary.
/// The keys are loaded from a column specified by and
/// values are loaded from a column specified by .
/// Other columns are ignored.
///
///The key type.
///The value type.
///The column name/index to load keys.
///The column name/index to load values.
///The loaded dictionary.
public Dictionary ExecuteScalarDictionary(
NameOrIndexParameter keyField,
NameOrIndexParameter valueField)
{
Dictionary dic = new Dictionary();
ExecuteScalarDictionary(dic, keyField, valueField);
return dic;
}
#endregion
#region ExecuteScalarDictionary (Index)
///
/// Executes the query, and returns the dictionary.
/// The keys are loaded from columns specified by and
/// values are loaded from a column specified by .
/// Other columns are ignored.
///
///The dictionary to add values.
///The of the key columns.
///The column name/index to load values.
///The value type.
///The loaded dictionary.
public IDictionary ExecuteScalarDictionary(
IDictionary dic,
MapIndex index,
NameOrIndexParameter valueField,
Type valueFieldType)
{
if (dic == null)
dic = new Hashtable();
if (_prepared)
InitParameters(CommandAction.Select);
//object nullValue = _mappingSchema.GetNullValue(type);
using (IDataReader dr = ExecuteReaderInternal())
{
if (dr.Read())
{
int valueIndex = valueField.ByName ? dr.GetOrdinal(valueField.Name) : valueField.Index;
int[] keyIndex = new int[index.Fields.Length];
for (int i = 0; i < keyIndex.Length; i++)
keyIndex[i] = index.Fields[i].ByName ?
dr.GetOrdinal(index.Fields[i].Name) : index.Fields[i].Index;
do
{
object value = dr[valueIndex];
if (value == null || value.GetType() != valueFieldType)
value = value is DBNull ? null : _mappingSchema.ConvertChangeType(value, valueFieldType);
object[] key = new object[keyIndex.Length];
for (int i = 0; i < keyIndex.Length; i++)
key[i] = dr[keyIndex[i]];
dic.Add(new CompoundValue(key), value);
}
while (dr.Read());
}
}
return dic;
}
///
/// Executes the query, and returns the dictionary.
/// The keys are loaded from columns specified by and
/// values are loaded from a column specified by .
/// Other columns are ignored.
///
///The of the key columns.
///The column name/index to load values.
///The value type.
///The loaded dictionary.
public Hashtable ExecuteScalarDictionary(
MapIndex index, NameOrIndexParameter valueField, Type valueFieldType)
{
Hashtable table = new Hashtable();
ExecuteScalarDictionary(table, index, valueField, valueFieldType);
return table;
}
///
/// Executes the query, and returns the dictionary.
/// The keys are loaded from columns specified by and
/// values are loaded from a column specified by .
/// Other columns are ignored.
///
///The value type.
///The dictionary to add values.
///The of the key columns.
///The column name/index to load values.
///The loaded dictionary.
public IDictionary ExecuteScalarDictionary(
IDictionary dic, MapIndex index, NameOrIndexParameter valueField)
{
if (dic == null)
dic = new Dictionary();
if (_prepared)
InitParameters(CommandAction.Select);
//object nullValue = _mappingSchema.GetNullValue(type);
Type valueFieldType = typeof(T);
using (IDataReader dr = ExecuteReaderInternal())
{
if (dr.Read())
{
int valueIndex = valueField.ByName ? dr.GetOrdinal(valueField.Name) : valueField.Index;
int[] keyIndex = new int[index.Fields.Length];
for (int i = 0; i < keyIndex.Length; i++)
keyIndex[i] = index.Fields[i].ByName ?
dr.GetOrdinal(index.Fields[i].Name) : index.Fields[i].Index;
do
{
object value = dr[valueIndex];
if (value == null || value.GetType() != valueFieldType)
value = value is DBNull ? null : _mappingSchema.ConvertChangeType(value, valueFieldType);
object[] key = new object[keyIndex.Length];
for (int i = 0; i < keyIndex.Length; i++)
key[i] = dr[keyIndex[i]];
dic.Add(new CompoundValue(key), (T)value);
}
while (dr.Read());
}
}
return dic;
}
///
/// Executes the query, and returns the dictionary.
/// The keys are loaded from columns specified by and
/// values are loaded from a column specified by .
/// Other columns are ignored.
///
///The value type.
///The of the key columns.
///The column name/index to load values.
///The loaded dictionary.
public Dictionary ExecuteScalarDictionary(
MapIndex index, NameOrIndexParameter valueField)
{
Dictionary dic = new Dictionary();
ExecuteScalarDictionary(dic, index, valueField);
return dic;
}
#endregion
#region ExecuteReader
///
/// Executes the command and builds an .
///
/// An instance of the class.
public IDataReader ExecuteReader()
{
if (_prepared)
InitParameters(CommandAction.Select);
return ExecuteReaderInternal();
}
///
/// Executes the command and builds an .
///
/// One of the values.
/// An instance of the class.
public IDataReader ExecuteReader(CommandBehavior commandBehavior)
{
if (_prepared)
InitParameters(CommandAction.Select);
return ExecuteReaderInternal(commandBehavior);
}
#endregion
#region ExecuteDataSet
///
/// Executes a SQL statement using the provided parameters.
///
///
/// See the method
/// to find an example.
///
/// The .
public DataSet ExecuteDataSet()
{
return ExecuteDataSet(null, 0, 0, "Table");
}
///
/// Executes a SQL statement using the provided parameters.
///
///
/// See the method
/// to find an example.
///
/// The input object.
/// The .
public DataSet ExecuteDataSet(
DataSet dataSet)
{
return ExecuteDataSet(dataSet, 0, 0, "Table");
}
///
/// Executes a SQL statement using the provided parameters.
///
///
/// See the method
/// to find an example.
///
/// The name or index of the populating table.
/// The .
public DataSet ExecuteDataSet(
NameOrIndexParameter table)
{
return ExecuteDataSet(null, 0, 0, table);
}
///
/// Executes a SQL statement using the provided parameters.
///
/// The object to populate.
/// The name or index of the populating table.
/// The .
public DataSet ExecuteDataSet(
DataSet dataSet,
NameOrIndexParameter table)
{
return ExecuteDataSet(dataSet, 0, 0, table);
}
///
/// Executes a SQL statement using the provided parameters.
///
/// The object to populate.
/// The name or index of the populating table.
/// The zero-based record number to start with.
/// The maximum number of records to retrieve.
/// The .
public DataSet ExecuteDataSet(
DataSet dataSet,
int startRecord,
int maxRecords,
NameOrIndexParameter table)
{
if (_prepared)
InitParameters(CommandAction.Select);
if (dataSet == null)
dataSet = new DataSet();
DbDataAdapter da = _dataProvider.CreateDataAdapterObject();
((IDbDataAdapter)da).SelectCommand = SelectCommand;
ExecuteOperation(OperationType.Fill, delegate
{
if (table.ByName)
da.Fill(dataSet, startRecord, maxRecords, table.Name);
else
da.Fill(startRecord, maxRecords, dataSet.Tables[table.Index]);
});
return dataSet;
}
#endregion
#region ExecuteDataTable
///
/// Executes a SQL statement using the provided parameters.
///
/// The .
public DataTable ExecuteDataTable()
{
return ExecuteDataTable(null);
}
///
/// Executes a SQL statement using the provided parameters.
///
/// The object to populate.
/// The .
public DataTable ExecuteDataTable(DataTable dataTable)
{
if (_prepared)
InitParameters(CommandAction.Select);
if (dataTable == null)
dataTable = new DataTable();
DbDataAdapter da = _dataProvider.CreateDataAdapterObject();
((IDbDataAdapter)da).SelectCommand = SelectCommand;
ExecuteOperation(OperationType.Fill, delegate { da.Fill(dataTable); });
return dataTable;
}
/// Adds or refreshes rows in a
/// to match those in the data source starting at the specified record
/// and retrieving up to the specified maximum number of records.
///
/// The zero-based record number to start with.
/// The maximum number of records to retrieve.
/// The objects
/// to fill from the data source.
public void ExecuteDataTables(
int startRecord,
int maxRecords,
params DataTable[] tableList)
{
if (tableList == null || tableList.Length == 0)
return;
if (_prepared)
InitParameters(CommandAction.Select);
DbDataAdapter da = _dataProvider.CreateDataAdapterObject();
((IDbDataAdapter)da).SelectCommand = SelectCommand;
ExecuteOperation(OperationType.Fill, delegate { da.Fill(startRecord, maxRecords, tableList); });
}
/// Adds or refreshes rows in a
/// to match those in the data source starting at the specified record
/// and retrieving up to the specified maximum number of records.
///
/// The objects
/// to fill from the data source.
public void ExecuteDataTables(params DataTable[] tableList)
{
ExecuteDataTables(0, 0, tableList);
}
#endregion
#region ExecuteObject
///
/// Executes a SQL statement and maps resultset to an object.
///
/// An object to populate.
/// The System.Type of the object.
/// Additional parameters passed to object constructor through .
/// A business object.
private object ExecuteObjectInternal(object entity, Type type, object[] parameters)
{
if (_prepared)
InitParameters(CommandAction.Select);
using (IDataReader dr = ExecuteReaderInternal(/*CommandBehavior.SingleRow*/)) // Sybase provider does not support this flag.
{
while (dr.Read())
{
return entity == null?
_mappingSchema.MapDataReaderToObject(dr, type, parameters):
_mappingSchema.MapDataReaderToObject(dr, entity, parameters);
}
return null;
}
}
///
/// Executes a SQL statement and maps resultset to an object.
///
/// An object to populate.
/// A business object.
public object ExecuteObject(object entity)
{
if (null == entity)
throw new ArgumentNullException("entity");
return ExecuteObjectInternal(entity, entity.GetType(), null);
}
///
/// Executes a SQL statement and maps resultset to an object.
///
/// An object to populate.
/// Additional parameters passed to object constructor through .
/// A business object.
public object ExecuteObject(object entity, params object[] parameters)
{
if (null == entity)
throw new ArgumentNullException("entity");
return ExecuteObjectInternal(entity, entity.GetType(), parameters);
}
///
/// Executes a SQL statement and maps resultset to an object.
///
/// Type of an object.
/// A business object.
public object ExecuteObject(Type type)
{
return ExecuteObjectInternal(null, type, null);
}
///
/// Executes a SQL statement and maps resultset to an object.
///
/// Type of an object.
/// Additional parameters passed to object constructor through .
/// A business object.
public object ExecuteObject(Type type, params object[] parameters)
{
return ExecuteObjectInternal(null, type, parameters);
}
///
/// Executes a SQL statement and maps resultset to an object.
///
/// Type of an object.
/// A business object.
public T ExecuteObject()
{
return (T)ExecuteObjectInternal(null, typeof(T), null);
}
///
/// Executes a SQL statement and maps resultset to an object.
///
/// Type of an object.
/// Additional parameters passed to object constructor through .
/// A business object.
public T ExecuteObject(params object[] parameters)
{
return (T)ExecuteObjectInternal(null, typeof(T), parameters);
}
#endregion
#region ExecuteList
private IList ExecuteListInternal(IList list, Type type, params object[] parameters)
{
if (list == null)
list = new ArrayList();
if (_prepared)
InitParameters(CommandAction.Select);
using (IDataReader dr = ExecuteReaderInternal())
{
return _mappingSchema.MapDataReaderToList(dr, list, type, parameters);
}
}
private void ExecuteListInternal(IList list, params object[] parameters)
{
if (list == null)
list = new List();
if (_prepared)
InitParameters(CommandAction.Select);
using (IDataReader dr = ExecuteReaderInternal())
{
_mappingSchema.MapDataReaderToList(dr, list, parameters);
}
}
///
/// Executes the query, and returns an array of business entities using the provided parameters.
///
/// Type of the business object.
/// An array of business objects.
public ArrayList ExecuteList(Type type)
{
ArrayList arrayList = new ArrayList();
ExecuteListInternal(arrayList, type, null);
return arrayList;
}
///
/// Executes the query, and returns an array of business entities.
///
/// Type of an object.
/// Populated list of mapped business objects.
public List ExecuteList()
{
List list = new List();
ExecuteListInternal(list, null);
return list;
}
///
/// Executes the query, and returns an array of business entities using the provided parameters.
///
/// Type of the business object.
/// Additional parameters passed to object constructor through .
/// An array of business objects.
public ArrayList ExecuteList(Type type, params object[] parameters)
{
ArrayList arrayList = new ArrayList();
ExecuteListInternal(arrayList, type, parameters);
return arrayList;
}
///
/// Executes the query, and returns an array of business entities.
///
/// Type of an object.
/// Additional parameters passed to object constructor through .
/// Populated list of mapped business objects.
public List ExecuteList(params object[] parameters)
{
List list = new List();
ExecuteListInternal(list, parameters);
return list;
}
///
/// Executes the query, and returns an array of business entities.
///
/// The list of mapped business objects to populate.
/// Type of an object.
/// Populated list of mapped business objects.
public IList ExecuteList(IList list, Type type)
{
return ExecuteListInternal(list, type, null);
}
///
/// Executes the query, and returns an array of business entities.
///
/// Type of an object.
/// The list of mapped business objects to populate.
/// Populated list of mapped business objects.
public IList ExecuteList(IList list)
{
ExecuteListInternal(list, null);
return list;
}
///
/// Executes the query, and returns an array of business entities.
///
/// The list of mapped business objects to populate.
/// Type of an object.
/// Additional parameters passed to object constructor through .
/// Populated list of mapped business objects.
public IList ExecuteList(IList list, Type type, params object[] parameters)
{
return ExecuteListInternal(list, type, parameters);
}
///
/// Executes the query, and returns an array of business entities.
///
/// Type of an object.
/// The list of mapped business objects to populate.
/// Additional parameters passed to object constructor through .
/// Populated list of mapped business objects.
public IList ExecuteList(IList list, params object[] parameters)
{
ExecuteListInternal(list, parameters);
return list;
}
///
/// Executes the query, and returns an array of business entities.
///
/// Type of a list.
/// Type of an object.
/// The list of mapped business objects to populate.
/// Additional parameters passed to object constructor through .
/// Populated list of mapped business objects.
public L ExecuteList(L list, params object[] parameters)
where L : IList
{
ExecuteListInternal(list, typeof(T), parameters);
return list;
}
///
/// Executes the query, and returns an array of business entities.
///
/// Type of a list.
/// Type of an object.
/// Additional parameters passed to object constructor through .
/// Populated list of mapped business objects.
public L ExecuteList(params object[] parameters)
where L : IList, new()
{
L list = new L();
ExecuteListInternal(list, typeof(T), parameters);
return list;
}
#endregion
#region ExecuteDictionary
///
/// Executes the query, and returns the of business entities
/// using the provided parameters.
///
///
/// The field name or index that is used as a key to populate .
/// Business object type.
/// Any additional parameters passed to the constructor with parameter.
/// An instance of the class.
public Hashtable ExecuteDictionary(
NameOrIndexParameter keyField,
Type keyFieldType,
params object[] parameters)
{
Hashtable hash = new Hashtable();
ExecuteDictionary(hash, keyField, keyFieldType, parameters);
return hash;
}
///
/// Executes the query, and returns the of business entities.
///
///
/// A dictionary of mapped business objects to populate.
/// The field name or index that is used as a key to populate .
/// Business object type.
/// Any additional parameters passed to the constructor with parameter.
/// An instance of the .
public IDictionary ExecuteDictionary(
IDictionary dictionary,
NameOrIndexParameter keyField,
Type type,
params object[] parameters)
{
if (dictionary == null)
dictionary = new Hashtable();
if (_prepared)
InitParameters(CommandAction.Select);
using (IDataReader dr = ExecuteReaderInternal())
{
return _mappingSchema.MapDataReaderToDictionary(dr, dictionary, keyField, type, parameters);
}
}
///
/// Executes the query, and returns a dictionary of business entities.
///
/// Key's type.
/// Value's type.
/// The field name or index that is used as a key to populate the dictionary.
/// Any additional parameters passed to the constructor with parameter.
/// An instance of the dictionary.
public Dictionary ExecuteDictionary(
NameOrIndexParameter keyField,
params object[] parameters)
{
Dictionary dictionary = new Dictionary();
ExecuteDictionary(dictionary, keyField, typeof(TValue), parameters);
return dictionary;
}
///
/// Executes the query, and returns the of business entities.
///
/// A dictionary of mapped business objects to populate.
/// The field name or index that is used as a key to populate .
/// Any additional parameters passed to the constructor with parameter.
/// An instance of the .
public IDictionary ExecuteDictionary(
IDictionary dictionary,
NameOrIndexParameter keyField,
params object[] parameters)
{
return ExecuteDictionary(dictionary, keyField, typeof(TValue), parameters);
}
///
/// Executes the query, and returns the of business entities.
///
/// A dictionary of mapped business objects to populate.
/// The field name or index that is used as a key to populate .
/// Business object type.
/// Any additional parameters passed to the constructor with parameter.
/// An instance of the .
public IDictionary ExecuteDictionary(
IDictionary dictionary,
NameOrIndexParameter keyField,
Type destObjectType,
params object[] parameters)
{
if (dictionary == null)
dictionary = new Dictionary();
if (_prepared)
InitParameters(CommandAction.Select);
using (IDataReader dr = ExecuteReaderInternal())
{
return _mappingSchema.MapDataReaderToDictionary(
dr, dictionary, keyField, destObjectType, parameters);
}
}
#endregion
#region ExecuteDictionary (Index)
///
/// Executes the query, and returns the of business entities
/// using the provided parameters.
///
///
/// Dictionary key fields.
/// Business object type.
/// Any additional parameters passed to the constructor with parameter.
/// An instance of the class.
public Hashtable ExecuteDictionary(
MapIndex index,
Type type,
params object[] parameters)
{
Hashtable hash = new Hashtable();
ExecuteDictionary(hash, index, type, parameters);
return hash;
}
///
/// Executes the query, and returns the of business entities.
///
///
/// A dictionary of mapped business objects to populate.
/// Dictionary key fields.
/// Business object type.
/// Any additional parameters passed to the constructor with parameter.
/// An instance of the .
public IDictionary ExecuteDictionary(
IDictionary dictionary,
MapIndex index,
Type type,
params object[] parameters)
{
if (dictionary == null)
dictionary = new Hashtable();
if (_prepared)
InitParameters(CommandAction.Select);
using (IDataReader dr = ExecuteReaderInternal())
{
return _mappingSchema.MapDataReaderToDictionary(dr, dictionary, index, type, parameters);
}
}
///
/// Executes the query, and returns a dictionary of business entities.
///
/// Value's type.
/// Dictionary key fields.
/// Any additional parameters passed to the constructor with parameter.
/// An instance of the dictionary.
public Dictionary ExecuteDictionary(
MapIndex index,
params object[] parameters)
{
Dictionary dictionary = new Dictionary();
ExecuteDictionary(dictionary, index, typeof(TValue), parameters);
return dictionary;
}
///
/// Executes the query, and returns a dictionary of business entities.
///
/// Value's type.
/// A dictionary of mapped business objects to populate.
/// Dictionary key fields.
/// Any additional parameters passed to the constructor with parameter.
/// An instance of the dictionary.
public IDictionary ExecuteDictionary(
IDictionary dictionary,
MapIndex index,
params object[] parameters)
{
return ExecuteDictionary(dictionary, index, typeof(TValue), parameters);
}
///
/// Executes the query, and returns a dictionary of business entities.
///
/// Value's type.
/// A dictionary of mapped business objects to populate.
/// Dictionary key fields.
/// Business object type.
/// Any additional parameters passed to the constructor with parameter.
/// An instance of the dictionary.
public IDictionary ExecuteDictionary(
IDictionary dictionary,
MapIndex index,
Type destObjectType,
params object[] parameters)
{
if (dictionary == null)
dictionary = new Dictionary();
if (_prepared)
InitParameters(CommandAction.Select);
using (IDataReader dr = ExecuteReaderInternal())
{
return _mappingSchema.MapDataReaderToDictionary(
dr, dictionary, index, destObjectType, parameters);
}
}
#endregion
#region ExecuteResultSet
///
/// Executes the query, and returns multiple results.
///
/// Array of to populate.
/// The populated .
public MapResultSet[] ExecuteResultSet(params MapResultSet[] resultSets)
{
if (_prepared)
InitParameters(CommandAction.Select);
using (IDataReader dr = ExecuteReaderInternal())
{
_mappingSchema.MapDataReaderToResultSet(dr, resultSets);
}
return resultSets;
}
///
/// Executes the query, and returns multiple results.
///
/// The type of the master business object.
/// Array of to populate.
/// The populated .
public MapResultSet[] ExecuteResultSet(
Type masterType, params MapNextResult[] nextResults)
{
return ExecuteResultSet(_mappingSchema.ConvertToResultSet(masterType, nextResults));
}
///
/// Executes the query, and returns multiple results.
///
/// The type of the master business object.
/// Array of to populate.
/// The populated .
public MapResultSet[] ExecuteResultSet(params MapNextResult[] nextResults)
{
return ExecuteResultSet(_mappingSchema.ConvertToResultSet(typeof(T), nextResults));
}
#endregion
#region Update
private DbDataAdapter CreateDataAdapter()
{
DbDataAdapter da = _dataProvider.CreateDataAdapterObject();
if (_insertCommand != null) ((IDbDataAdapter)da).InsertCommand = InsertCommand;
if (_updateCommand != null) ((IDbDataAdapter)da).UpdateCommand = UpdateCommand;
if (_deleteCommand != null) ((IDbDataAdapter)da).DeleteCommand = DeleteCommand;
return da;
}
///
/// Calls the corresponding INSERT, UPDATE, or DELETE statements for each inserted, updated, or
/// deleted row in the specified .
///
/// The used to update the data source.
/// The number of rows successfully updated from the .
public int Update(DataSet dataSet)
{
return Update(dataSet, "Table");
}
///
/// Calls the corresponding INSERT, UPDATE, or DELETE statements for each inserted, updated, or
/// deleted row in the with the specified name.
///
/// The used to update the data source.
/// The name or index of the source table to use for table mapping.
/// The number of rows successfully updated from the .
public int Update(
DataSet dataSet,
NameOrIndexParameter table)
{
if (dataSet == null)
throw new ArgumentNullException(
"dataSet", Resources.DbManager_CannotUpdateNullDataset);
DbDataAdapter da = CreateDataAdapter();
return ExecuteOperation(OperationType.Update, delegate
{
return (table.ByName) ?
da.Update(dataSet, table.Name) :
da.Update(dataSet.Tables[table.Index]);
});
}
///
/// Calls the corresponding INSERT, UPDATE, or DELETE statements for
/// each inserted, updated, or deleted row in the specified
/// .
///
/// The name or index of the source table to
/// use for table mapping.
/// The number of rows successfully updated from the
/// .
public int Update(DataTable dataTable)
{
if (dataTable == null)
throw new ArgumentNullException(
"dataTable", Resources.DbManager_CannotUpdateNullDataTable);
return ExecuteOperation(OperationType.Update, delegate
{
return CreateDataAdapter().Update(dataTable);
});
}
#endregion
#region ExecuteOperation
private void ExecuteOperation(OperationType operationType, Action operation)
{
try
{
OnBeforeOperation(operationType);
operation();
OnAfterOperation (operationType);
}
catch (Exception ex)
{
HandleOperationException(operationType, ex);
throw;
}
}
private T ExecuteOperation(OperationType operationType, Func operation)
{
T res = default(T);
try
{
OnBeforeOperation(operationType);
res = operation();
OnAfterOperation (operationType);
}
catch (Exception ex)
{
if (res is IDisposable)
((IDisposable)res).Dispose();
HandleOperationException(operationType, ex);
throw;
}
return res;
}
private void HandleOperationException(OperationType op, Exception ex)
{
DataException dex = new DataException(this, ex);
Debug.WriteLineIf(TraceSwitch.TraceError, string.Format(
"Operation '{0}' throws exception '{1}'", op, dex), TraceSwitch.DisplayName);
OnOperationException(op, dex);
}
#endregion
#region IDisposable interface
///
/// Releases the unmanaged resources used by the and
/// optionally releases the managed resources.
///
///
/// This method is called by the public method
/// and the Finalize method.
///
/// true to release both managed and unmanaged resources; false to release only unmanaged resources.
protected override void Dispose(bool disposing)
{
if (disposing)
Close();
base.Dispose(disposing);
}
#endregion
}
}