#region Apache Notice
/*****************************************************************************
* $Revision$
* $LastChangedDate$
* $LastChangedBy$
*
* iBATIS.NET Data Mapper
* Copyright (C) 2006/2005 - The Apache Software Foundation
*
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
********************************************************************************/
#endregion
#region Using
using System;
using System.Collections;
#if dotnet2
using System.Collections.Generic;
#endif
using System.Data;
using System.Text;
using IBatisNet.Common.Utilities.Objects;
using IBatisNet.DataMapper.Commands;
using IBatisNet.DataMapper.Configuration.ParameterMapping;
using IBatisNet.DataMapper.Configuration.Statements;
using IBatisNet.DataMapper.MappedStatements.ResultStrategy;
using IBatisNet.DataMapper.Scope;
using IBatisNet.DataMapper.MappedStatements.PostSelectStrategy;
using IBatisNet.DataMapper.Exceptions;
using IBatisNet.DataMapper.TypeHandlers;
#endregion
namespace IBatisNet.DataMapper.MappedStatements
{
///
/// Summary description for MappedStatement.
///
public class MappedStatement : IMappedStatement
{
///
/// Event launch on exceute query
///
public event ExecuteEventHandler Execute;
#region Fields
// Magic number used to set the the maximum number of rows returned to 'all'.
internal const int NO_MAXIMUM_RESULTS = -1;
// Magic number used to set the the number of rows skipped to 'none'.
internal const int NO_SKIPPED_RESULTS = -1;
private IStatement _statement = null;
private ISqlMapper _sqlMap = null;
private IPreparedCommand _preparedCommand = null;
private IResultStrategy _resultStrategy = null;
#endregion
#region Properties
///
/// The IPreparedCommand to use
///
public IPreparedCommand PreparedCommand
{
get { return _preparedCommand; }
}
///
/// Name used to identify the MappedStatement amongst the others.
/// This the name of the SQL statement by default.
///
public string Id
{
get { return _statement.Id; }
}
///
/// The SQL statment used by this MappedStatement
///
public IStatement Statement
{
get { return _statement; }
}
///
/// The SqlMap used by this MappedStatement
///
public ISqlMapper SqlMap
{
get { return _sqlMap; }
}
#endregion
#region Constructor (s) / Destructor
///
/// Constructor
///
/// An SqlMap
/// An SQL statement
internal MappedStatement(ISqlMapper sqlMap, IStatement statement)
{
_sqlMap = sqlMap;
_statement = statement;
_preparedCommand = PreparedCommandFactory.GetPreparedCommand(false);
_resultStrategy = ResultStrategyFactory.Get(_statement);
}
#endregion
#region Methods
///
/// Retrieve the output parameter and map them on the result object.
/// This routine is only use is you specified a ParameterMap and some output attribute
/// or if you use a store procedure with output parameter...
///
///
/// The current session.
/// The result object.
/// The command sql.
private void RetrieveOutputParameters(RequestScope request, ISqlMapSession session, IDbCommand command, object result)
{
if (request.ParameterMap != null)
{
int count = request.ParameterMap.PropertiesList.Count;
for (int i = 0; i < count; i++)
{
ParameterProperty mapping = request.ParameterMap.GetProperty(i);
if (mapping.Direction == ParameterDirection.Output ||
mapping.Direction == ParameterDirection.InputOutput)
{
string parameterName = string.Empty;
if (session.DataSource.DbProvider.UseParameterPrefixInParameter == false)
{
parameterName = mapping.ColumnName;
}
else
{
parameterName = session.DataSource.DbProvider.ParameterPrefix +
mapping.ColumnName;
}
if (mapping.TypeHandler == null) // Find the TypeHandler
{
lock (mapping)
{
if (mapping.TypeHandler == null)
{
Type propertyType = ObjectProbe.GetMemberTypeForGetter(result, mapping.PropertyName);
mapping.TypeHandler = request.DataExchangeFactory.TypeHandlerFactory.GetTypeHandler(propertyType);
}
}
}
// Fix IBATISNET-239
//"Normalize" System.DBNull parameters
IDataParameter dataParameter = (IDataParameter)command.Parameters[parameterName];
object dbValue = dataParameter.Value;
object value = null;
bool wasNull = (dbValue == DBNull.Value);
if (wasNull)
{
if (mapping.HasNullValue)
{
value = mapping.TypeHandler.ValueOf(mapping.GetAccessor.MemberType, mapping.NullValue);
}
else
{
value = mapping.TypeHandler.NullValue;
}
}
else
{
value = mapping.TypeHandler.GetDataBaseValue(dataParameter.Value, result.GetType());
}
request.IsRowDataFound = request.IsRowDataFound || (value != null);
request.ParameterMap.SetOutputParameter(ref result, mapping, value);
}
}
}
}
#region ExecuteForObject
///
/// Executes an SQL statement that returns a single row as an Object.
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// The object
public virtual object ExecuteQueryForObject(ISqlMapSession session, object parameterObject)
{
return ExecuteQueryForObject(session, parameterObject, null);
}
///
/// Executes an SQL statement that returns a single row as an Object of the type of
/// the resultObject passed in as a parameter.
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// The result object.
/// The object
public virtual object ExecuteQueryForObject(ISqlMapSession session, object parameterObject, object resultObject)
{
object obj = null;
RequestScope request = _statement.Sql.GetRequestScope(this, parameterObject, session);
_preparedCommand.Create(request, session, this.Statement, parameterObject);
obj = RunQueryForObject(request, session, parameterObject, resultObject);
return obj;
}
///
/// Executes an SQL statement that returns a single row as an Object of the type of
/// the resultObject passed in as a parameter.
///
/// The request scope.
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// The result object.
/// The object
internal object RunQueryForObject(RequestScope request, ISqlMapSession session, object parameterObject, object resultObject)
{
object result = resultObject;
using (IDbCommand command = request.IDbCommand)
{
IDataReader reader = command.ExecuteReader();
try
{
while (reader.Read())
{
object obj = _resultStrategy.Process(request, ref reader, resultObject);
if (obj != BaseStrategy.SKIP)
{
result = obj;
}
}
}
catch
{
throw;
}
finally
{
reader.Close();
reader.Dispose();
}
ExecutePostSelect(request);
#region remark
// If you are using the OleDb data provider (as you are), you need to close the
// DataReader before output parameters are visible.
#endregion
RetrieveOutputParameters(request, session, command, parameterObject);
}
RaiseExecuteEvent();
return result;
}
#endregion
#region ExecuteForObject .NET 2.0
#if dotnet2
///
/// Executes an SQL statement that returns a single row as an Object.
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// The object
public virtual T ExecuteQueryForObject(ISqlMapSession session, object parameterObject)
{
return ExecuteQueryForObject(session, parameterObject, default(T));
}
///
/// Executes an SQL statement that returns a single row as an Object of the type of
/// the resultObject passed in as a parameter.
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// The result object.
/// The object
public virtual T ExecuteQueryForObject(ISqlMapSession session, object parameterObject, T resultObject)
{
T obj = default(T);
RequestScope request = _statement.Sql.GetRequestScope(this, parameterObject, session);
_preparedCommand.Create(request, session, this.Statement, parameterObject);
obj = RunQueryForObject(request, session, parameterObject, resultObject);
return obj;
}
///
/// Executes an SQL statement that returns a single row as an Object of the type of
/// the resultObject passed in as a parameter.
///
/// The request scope.
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// The result object.
/// The object
internal T RunQueryForObject(RequestScope request, ISqlMapSession session, object parameterObject, T resultObject)
{
T result = resultObject;
using (IDbCommand command = request.IDbCommand)
{
IDataReader reader = command.ExecuteReader();
try
{
while (reader.Read())
{
object obj = _resultStrategy.Process(request, ref reader, resultObject);
if (obj != BaseStrategy.SKIP)
{
result = (T)obj;
}
}
}
catch
{
throw;
}
finally
{
reader.Close();
reader.Dispose();
}
ExecutePostSelect(request);
#region remark
// If you are using the OleDb data provider, you need to close the
// DataReader before output parameters are visible.
#endregion
RetrieveOutputParameters(request, session, command, parameterObject);
}
RaiseExecuteEvent();
return result;
}
#endif
#endregion
#region ExecuteQueryForList
///
/// Runs a query with a custom object that gets a chance
/// to deal with each row as it is processed.
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
///
public virtual IList ExecuteQueryForRowDelegate(ISqlMapSession session, object parameterObject, RowDelegate rowDelegate)
{
RequestScope request = _statement.Sql.GetRequestScope(this, parameterObject, session);
_preparedCommand.Create(request, session, this.Statement, parameterObject);
if (rowDelegate == null)
{
throw new DataMapperException("A null RowDelegate was passed to QueryForRowDelegate.");
}
return RunQueryForList(request, session, parameterObject, null, rowDelegate);
}
///
/// Runs a query with a custom object that gets a chance
/// to deal with each row as it is processed.
///
/// The session used to execute the statement
/// The object used to set the parameters in the SQL.
/// The property of the result object to be used as the key.
/// The property of the result object to be used as the value (or null)
///
/// A hashtable of object containing the rows keyed by keyProperty.
///If a transaction is not in progress, or the database throws an exception.
public virtual IDictionary ExecuteQueryForMapWithRowDelegate(ISqlMapSession session, object parameterObject, string keyProperty, string valueProperty, DictionaryRowDelegate rowDelegate)
{
RequestScope request = _statement.Sql.GetRequestScope(this, parameterObject, session);
if (rowDelegate == null)
{
throw new DataMapperException("A null DictionaryRowDelegate was passed to QueryForMapWithRowDelegate.");
}
_preparedCommand.Create(request, session, this.Statement, parameterObject);
return RunQueryForMap(request, session, parameterObject, keyProperty, valueProperty, rowDelegate);
}
///
/// Executes the SQL and retuns all rows selected. This is exactly the same as
/// calling ExecuteQueryForList(session, parameterObject, NO_SKIPPED_RESULTS, NO_MAXIMUM_RESULTS).
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// A List of result objects.
public virtual IList ExecuteQueryForList(ISqlMapSession session, object parameterObject)
{
RequestScope request = _statement.Sql.GetRequestScope(this, parameterObject, session);
_preparedCommand.Create(request, session, this.Statement, parameterObject);
return RunQueryForList(request, session, parameterObject, null, null);
}
///
/// Executes the SQL and retuns a subset of the rows selected.
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// The number of rows to skip over.
/// The maximum number of rows to return.
/// A List of result objects.
public virtual IList ExecuteQueryForList(ISqlMapSession session, object parameterObject, int skipResults, int maxResults)
{
RequestScope request = _statement.Sql.GetRequestScope(this, parameterObject, session);
_preparedCommand.Create(request, session, this.Statement, parameterObject);
return RunQueryForList(request, session, parameterObject, skipResults, maxResults);
}
///
/// Runs the query for list.
///
/// The request.
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// The number of rows to skip over.
/// The maximum number of rows to return.
/// A List of result objects.
internal IList RunQueryForList(RequestScope request, ISqlMapSession session, object parameterObject, int skipResults, int maxResults)
{
IList list = null;
using (IDbCommand command = request.IDbCommand)
{
if (_statement.ListClass == null)
{
list = new ArrayList();
}
else
{
list = _statement.CreateInstanceOfListClass();
}
IDataReader reader = command.ExecuteReader();
try
{
// skip results
for (int i = 0; i < skipResults; i++)
{
if (!reader.Read())
{
break;
}
}
// Get Results
int resultsFetched = 0;
while ((maxResults == NO_MAXIMUM_RESULTS || resultsFetched < maxResults)
&& reader.Read())
{
object obj = _resultStrategy.Process(request, ref reader, null);
if (obj != BaseStrategy.SKIP)
{
list.Add(obj);
}
resultsFetched++;
}
}
catch
{
throw;
}
finally
{
reader.Close();
reader.Dispose();
}
ExecutePostSelect(request);
RetrieveOutputParameters(request, session, command, parameterObject);
}
return list;
}
///
/// Executes the SQL and retuns a List of result objects.
///
/// The request scope.
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// A strongly typed collection of result objects.
///
/// A List of result objects.
internal IList RunQueryForList(RequestScope request, ISqlMapSession session, object parameterObject, IList resultObject, RowDelegate rowDelegate)
{
IList list = resultObject;
using (IDbCommand command = request.IDbCommand)
{
if (resultObject==null)
{
if (_statement.ListClass == null)
{
list = new ArrayList();
}
else
{
list = _statement.CreateInstanceOfListClass();
}
}
IDataReader reader = command.ExecuteReader();
try
{
do
{
if (rowDelegate == null)
{
while (reader.Read())
{
object obj = _resultStrategy.Process(request, ref reader, null);
if (obj != BaseStrategy.SKIP)
{
list.Add(obj);
}
}
}
else
{
while (reader.Read())
{
object obj = _resultStrategy.Process(request, ref reader, null);
rowDelegate(obj, parameterObject, list);
}
}
}
while (reader.NextResult());
}
catch
{
throw;
}
finally
{
reader.Close();
reader.Dispose();
}
ExecutePostSelect(request);
RetrieveOutputParameters(request, session, command, parameterObject);
}
return list;
}
///
/// Executes the SQL and and fill a strongly typed collection.
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// A strongly typed collection of result objects.
public virtual void ExecuteQueryForList(ISqlMapSession session, object parameterObject, IList resultObject)
{
RequestScope request = _statement.Sql.GetRequestScope(this, parameterObject, session);
_preparedCommand.Create(request, session, this.Statement, parameterObject);
RunQueryForList(request, session, parameterObject, resultObject, null);
}
#endregion
#region ExecuteQueryForList .NET 2.0
#if dotnet2
///
/// Runs a query with a custom object that gets a chance
/// to deal with each row as it is processed.
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
///
public virtual IList ExecuteQueryForRowDelegate(ISqlMapSession session, object parameterObject, RowDelegate rowDelegate)
{
RequestScope request = _statement.Sql.GetRequestScope(this, parameterObject, session);
_preparedCommand.Create(request, session, this.Statement, parameterObject);
if (rowDelegate == null)
{
throw new DataMapperException("A null RowDelegate was passed to QueryForRowDelegate.");
}
return RunQueryForList(request, session, parameterObject, null, rowDelegate);
}
///
/// Executes the SQL and retuns all rows selected. This is exactly the same as
/// calling ExecuteQueryForList(session, parameterObject, NO_SKIPPED_RESULTS, NO_MAXIMUM_RESULTS).
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// A List of result objects.
public virtual IList ExecuteQueryForList(ISqlMapSession session, object parameterObject)
{
RequestScope request = _statement.Sql.GetRequestScope(this, parameterObject, session);
_preparedCommand.Create(request, session, this.Statement, parameterObject);
return RunQueryForList(request, session, parameterObject, null, null);
}
///
/// Executes the SQL and retuns a subset of the rows selected.
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// The number of rows to skip over.
/// The maximum number of rows to return.
/// A List of result objects.
public virtual IList ExecuteQueryForList(ISqlMapSession session, object parameterObject, int skipResults, int maxResults)
{
RequestScope request = _statement.Sql.GetRequestScope(this, parameterObject, session);
_preparedCommand.Create(request, session, this.Statement, parameterObject);
return RunQueryForList(request, session, parameterObject, skipResults, maxResults);
}
///
/// Executes the SQL and retuns a List of result objects.
///
/// The request scope.
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// The number of rows to skip over.
/// The maximum number of rows to return.
/// A List of result objects.
internal IList RunQueryForList(RequestScope request, ISqlMapSession session, object parameterObject, int skipResults, int maxResults)
{
IList list = null;
using (IDbCommand command = request.IDbCommand)
{
if (_statement.ListClass == null)
{
list = new List();
}
else
{
list = _statement.CreateInstanceOfGenericListClass();
}
IDataReader reader = command.ExecuteReader();
try
{
// skip results
for (int i = 0; i < skipResults; i++)
{
if (!reader.Read())
{
break;
}
}
int resultsFetched = 0;
while ((maxResults == NO_MAXIMUM_RESULTS || resultsFetched < maxResults)
&& reader.Read())
{
object obj = _resultStrategy.Process(request, ref reader, null);
if (obj != BaseStrategy.SKIP)
{
list.Add((T)obj);
}
resultsFetched++;
}
}
catch
{
throw;
}
finally
{
reader.Close();
reader.Dispose();
}
ExecutePostSelect(request);
RetrieveOutputParameters(request, session, command, parameterObject);
}
return list;
}
///
/// Executes the SQL and retuns a List of result objects.
///
/// The request scope.
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// The result object
///
/// A List of result objects.
internal IList RunQueryForList(RequestScope request, ISqlMapSession session,
object parameterObject, IList resultObject, RowDelegate rowDelegate)
{
IList list = resultObject;
using (IDbCommand command = request.IDbCommand)
{
if (resultObject == null)
{
if (_statement.ListClass == null)
{
list = new List();
}
else
{
list = _statement.CreateInstanceOfGenericListClass();
}
}
IDataReader reader = command.ExecuteReader();
try
{
do
{
if (rowDelegate == null)
{
while (reader.Read())
{
object obj = _resultStrategy.Process(request, ref reader, null);
if (obj != BaseStrategy.SKIP)
{
list.Add((T)obj);
}
}
}
else
{
while (reader.Read())
{
T obj = (T)_resultStrategy.Process(request, ref reader, null);
rowDelegate(obj, parameterObject, list);
}
}
}
while (reader.NextResult());
}
catch
{
throw;
}
finally
{
reader.Close();
reader.Dispose();
}
ExecutePostSelect(request);
RetrieveOutputParameters(request, session, command, parameterObject);
}
return list;
}
///
/// Executes the SQL and and fill a strongly typed collection.
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// A strongly typed collection of result objects.
public virtual void ExecuteQueryForList(ISqlMapSession session, object parameterObject, IList resultObject)
{
RequestScope request = _statement.Sql.GetRequestScope(this, parameterObject, session);
_preparedCommand.Create(request, session, this.Statement, parameterObject);
RunQueryForList(request, session, parameterObject, resultObject, null);
}
#endif
#endregion
#region ExecuteUpdate, ExecuteInsert
///
/// Execute an update statement. Also used for delete statement.
/// Return the number of row effected.
///
/// The session used to execute the statement.
/// The object used to set the parameters in the SQL.
/// The number of row effected.
public virtual int ExecuteUpdate(ISqlMapSession session, object parameterObject)
{
int rows = 0; // the number of rows affected
RequestScope request = _statement.Sql.GetRequestScope(this, parameterObject, session);
_preparedCommand.Create(request, session, this.Statement, parameterObject);
using (IDbCommand command = request.IDbCommand)
{
rows = command.ExecuteNonQuery();
//ExecutePostSelect(request);
RetrieveOutputParameters(request, session, command, parameterObject);
}
RaiseExecuteEvent();
return rows;
}
///
/// Execute an insert statement. Fill the parameter object with
/// the ouput parameters if any, also could return the insert generated key
///
/// The session
/// The parameter object used to fill the statement.
/// Can return the insert generated key.
public virtual object ExecuteInsert(ISqlMapSession session, object parameterObject)
{
object generatedKey = null;
SelectKey selectKeyStatement = null;
RequestScope request = _statement.Sql.GetRequestScope(this, parameterObject, session);
if (_statement is Insert)
{
selectKeyStatement = ((Insert)_statement).SelectKey;
}
if (selectKeyStatement != null && !selectKeyStatement.isAfter)
{
IMappedStatement mappedStatement = _sqlMap.GetMappedStatement(selectKeyStatement.Id);
generatedKey = mappedStatement.ExecuteQueryForObject(session, parameterObject);
ObjectProbe.SetMemberValue(parameterObject, selectKeyStatement.PropertyName, generatedKey,
request.DataExchangeFactory.ObjectFactory,
request.DataExchangeFactory.AccessorFactory);
}
_preparedCommand.Create(request, session, this.Statement, parameterObject);
using (IDbCommand command = request.IDbCommand)
{
if (_statement is Insert)
{
command.ExecuteNonQuery();
}
// Retrieve output parameter if the result class is specified
else if (_statement is Procedure && (_statement.ResultClass != null) &&
_sqlMap.TypeHandlerFactory.IsSimpleType(_statement.ResultClass))
{
IDataParameter returnValueParameter = command.CreateParameter();
returnValueParameter.Direction = ParameterDirection.ReturnValue;
command.Parameters.Add(returnValueParameter);
command.ExecuteNonQuery();
generatedKey = returnValueParameter.Value;
ITypeHandler typeHandler = _sqlMap.TypeHandlerFactory.GetTypeHandler(_statement.ResultClass);
generatedKey = typeHandler.GetDataBaseValue(generatedKey, _statement.ResultClass);
}
else
{
generatedKey = command.ExecuteScalar();
if ((_statement.ResultClass != null) &&
_sqlMap.TypeHandlerFactory.IsSimpleType(_statement.ResultClass))
{
ITypeHandler typeHandler = _sqlMap.TypeHandlerFactory.GetTypeHandler(_statement.ResultClass);
generatedKey = typeHandler.GetDataBaseValue(generatedKey, _statement.ResultClass);
}
}
if (selectKeyStatement != null && selectKeyStatement.isAfter)
{
IMappedStatement mappedStatement = _sqlMap.GetMappedStatement(selectKeyStatement.Id);
generatedKey = mappedStatement.ExecuteQueryForObject(session, parameterObject);
ObjectProbe.SetMemberValue(parameterObject, selectKeyStatement.PropertyName, generatedKey,
request.DataExchangeFactory.ObjectFactory,
request.DataExchangeFactory.AccessorFactory);
}
//ExecutePostSelect(request);
RetrieveOutputParameters(request, session, command, parameterObject);
}
RaiseExecuteEvent();
return generatedKey;
}
#endregion
#region ExecuteQueryForMap
///
/// Executes the SQL and retuns all rows selected in a map that is keyed on the property named
/// in the keyProperty parameter. The value at each key will be the value of the property specified
/// in the valueProperty parameter. If valueProperty is null, the entire result object will be entered.
///
/// The session used to execute the statement
/// The object used to set the parameters in the SQL.
/// The property of the result object to be used as the key.
/// The property of the result object to be used as the value (or null)
/// A hashtable of object containing the rows keyed by keyProperty.
///If a transaction is not in progress, or the database throws an exception.
public virtual IDictionary ExecuteQueryForMap(ISqlMapSession session, object parameterObject, string keyProperty, string valueProperty)
{
RequestScope request = _statement.Sql.GetRequestScope(this, parameterObject, session);
_preparedCommand.Create(request, session, this.Statement, parameterObject);
return RunQueryForMap(request, session, parameterObject, keyProperty, valueProperty, null);
}
///
/// Executes the SQL and retuns all rows selected in a map that is keyed on the property named
/// in the keyProperty parameter. The value at each key will be the value of the property specified
/// in the valueProperty parameter. If valueProperty is null, the entire result object will be entered.
///
/// The request scope.
/// The session used to execute the statement
/// The object used to set the parameters in the SQL.
/// The property of the result object to be used as the key.
/// The property of the result object to be used as the value (or null)
/// A delegate called once per row in the QueryForMapWithRowDelegate method
/// A hashtable of object containing the rows keyed by keyProperty.
///If a transaction is not in progress, or the database throws an exception.
internal IDictionary RunQueryForMap(RequestScope request,
ISqlMapSession session,
object parameterObject,
string keyProperty,
string valueProperty,
DictionaryRowDelegate rowDelegate)
{
IDictionary map = new Hashtable();
using (IDbCommand command = request.IDbCommand)
{
IDataReader reader = command.ExecuteReader();
try
{
if (rowDelegate == null)
{
while (reader.Read())
{
object obj = _resultStrategy.Process(request, ref reader, null);
object key = ObjectProbe.GetMemberValue(obj, keyProperty, request.DataExchangeFactory.AccessorFactory);
object value = obj;
if (valueProperty != null)
{
value = ObjectProbe.GetMemberValue(obj, valueProperty, request.DataExchangeFactory.AccessorFactory);
}
map.Add(key, value);
}
}
else
{
while (reader.Read())
{
object obj = _resultStrategy.Process(request, ref reader, null);
object key = ObjectProbe.GetMemberValue(obj, keyProperty, request.DataExchangeFactory.AccessorFactory);
object value = obj;
if (valueProperty != null)
{
value = ObjectProbe.GetMemberValue(obj, valueProperty, request.DataExchangeFactory.AccessorFactory);
}
rowDelegate(key, value, parameterObject, map);
}
}
}
catch
{
throw;
}
finally
{
reader.Close();
reader.Dispose();
}
ExecutePostSelect(request);
}
return map;
}
#if dotnet2
///
/// Executes the SQL and retuns all rows selected in a map that is keyed on the property named
/// in the keyProperty parameter. The value at each key will be the value of the property specified
/// in the valueProperty parameter. If valueProperty is null, the entire result object will be entered.
///
/// The session used to execute the statement
/// The object used to set the parameters in the SQL.
/// The property of the result object to be used as the key.
/// The property of the result object to be used as the value (or null)
/// A IDictionary of object containing the rows keyed by keyProperty.
///If a transaction is not in progress, or the database throws an exception.
public virtual IDictionary ExecuteQueryForDictionary(ISqlMapSession session, object parameterObject, string keyProperty, string valueProperty)
{
RequestScope request = _statement.Sql.GetRequestScope(this, parameterObject, session);
_preparedCommand.Create(request, session, this.Statement, parameterObject);
return RunQueryForDictionary(request, session, parameterObject, keyProperty, valueProperty, null);
}
///
/// Runs a query with a custom object that gets a chance
/// to deal with each row as it is processed.
///
/// The session used to execute the statement
/// The object used to set the parameters in the SQL.
/// The property of the result object to be used as the key.
/// The property of the result object to be used as the value (or null)
/// A delegate called once per row in the QueryForDictionary method
/// A hashtable of object containing the rows keyed by keyProperty.
///If a transaction is not in progress, or the database throws an exception.
public virtual IDictionary ExecuteQueryForDictionary(ISqlMapSession session, object parameterObject, string keyProperty, string valueProperty, DictionaryRowDelegate rowDelegate)
{
RequestScope request = _statement.Sql.GetRequestScope(this, parameterObject, session);
if (rowDelegate == null)
{
throw new DataMapperException("A null DictionaryRowDelegate was passed to QueryForDictionary.");
}
_preparedCommand.Create(request, session, this.Statement, parameterObject);
return RunQueryForDictionary(request, session, parameterObject, keyProperty, valueProperty, rowDelegate);
}
///
/// Executes the SQL and retuns all rows selected in a map that is keyed on the property named
/// in the keyProperty parameter. The value at each key will be the value of the property specified
/// in the valueProperty parameter. If valueProperty is null, the entire result object will be entered.
///
/// The request scope.
/// The session used to execute the statement
/// The object used to set the parameters in the SQL.
/// The property of the result object to be used as the key.
/// The property of the result object to be used as the value (or null)
/// A delegate called once per row in the QueryForMapWithRowDelegate method
/// A IDictionary of object containing the rows keyed by keyProperty.
///If a transaction is not in progress, or the database throws an exception.
internal IDictionary RunQueryForDictionary(RequestScope request,
ISqlMapSession session,
object parameterObject,
string keyProperty,
string valueProperty,
DictionaryRowDelegate rowDelegate)
{
IDictionary map = new Dictionary();
using (IDbCommand command = request.IDbCommand)
{
IDataReader reader = command.ExecuteReader();
try
{
if (rowDelegate == null)
{
while (reader.Read())
{
object obj = _resultStrategy.Process(request, ref reader, null);
K key = (K)ObjectProbe.GetMemberValue(obj, keyProperty, request.DataExchangeFactory.AccessorFactory);
V value = default(V);
if (valueProperty != null)
{
value = (V)ObjectProbe.GetMemberValue(obj, valueProperty, request.DataExchangeFactory.AccessorFactory);
}
else
{
value = (V)obj;
}
map.Add(key, value);
}
}
else
{
while (reader.Read())
{
object obj = _resultStrategy.Process(request, ref reader, null);
K key = (K)ObjectProbe.GetMemberValue(obj, keyProperty, request.DataExchangeFactory.AccessorFactory);
V value = default(V);
if (valueProperty != null)
{
value = (V)ObjectProbe.GetMemberValue(obj, valueProperty, request.DataExchangeFactory.AccessorFactory);
}
else
{
value = (V)obj;
}
rowDelegate(key, value, parameterObject, map);
}
}
}
catch
{
throw;
}
finally
{
reader.Close();
reader.Dispose();
}
ExecutePostSelect(request);
}
return map;
}
#endif
#endregion
///
/// Executes the .
///
/// The current .
private void ExecutePostSelect(RequestScope request)
{
while (request.QueueSelect.Count > 0)
{
PostBindind postSelect = request.QueueSelect.Dequeue() as PostBindind;
PostSelectStrategyFactory.Get(postSelect.Method).Execute(postSelect, request);
}
}
///
/// Raise an event ExecuteEventArgs
/// (Used when a query is executed)
///
private void RaiseExecuteEvent()
{
ExecuteEventArgs e = new ExecuteEventArgs();
e.StatementName = _statement.Id;
if (Execute != null)
{
Execute(this, e);
}
}
///
/// ToString implementation.
///
/// A string that describes the MappedStatement
public override string ToString()
{
StringBuilder buffer = new StringBuilder();
buffer.Append("\tMappedStatement: " + this.Id);
buffer.Append(Environment.NewLine);
if (_statement.ParameterMap != null) buffer.Append(_statement.ParameterMap.Id);
return buffer.ToString();
}
#endregion
}
}