#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 } }