/// <summary>
        /// Records the results of calling execute scalar on the command
        /// </summary>
        /// <returns>The result of executing the command</returns>
        private MockQueryResult RecordExecuteScalar()
        {
            MockQueryResult mockResult = new MockQueryResult();

            using (SqlConnection connection = this.CreateSqlConnection())
            {
                connection.Open();

                SqlCommand cmd = connection.CreateCommand();
                cmd.CommandTimeout = 120;
                cmd.CommandType    = this.CommandType;
                cmd.CommandText    = this.CommandText;

                foreach (DbParameter param in this.Parameters)
                {
                    SqlParameter sqlParam = new SqlParameter(param.ParameterName, param.DbType);
                    sqlParam.Value = param.Value;
                    cmd.Parameters.Add(sqlParam);
                }

                mockResult.ScalarResult = cmd.ExecuteScalar();

                mockResult.CommandText  = this.GetCommandKey();
                mockResult.DatabaseName = this.DbConnection.Database;
                mockResult.MockId       = this.settings.MockId;
            }

            this.SaveMockResult(mockResult);

            return(mockResult);
        }
        /// <summary>
        /// Executes the database data reader command using mock framework
        /// </summary>
        /// <param name="behavior">The command behaviour</param>
        /// <returns>A database data reader</returns>
        protected override DbDataReader ExecuteDbDataReader(CommandBehavior behavior)
        {
            Assert.IsTrue((this.Connection.State & ConnectionState.Open) == ConnectionState.Open, "Connection has to be opened when executing a command");

            MockQueryResult mockResult = null;

            if (this.settings.RecordingMode)
            {
                mockResult = this.RecordExecuteDbDataReader();
            }
            else
            {
                string commandKey = this.GetCommandKey();
                mockResult = FindMockResult(this.settings.MockId, this.Connection.Database, commandKey, this.settings.IsolatedQueries);

                if (mockResult == null || mockResult.DataSetResult == null)
                {
                    if (mockResult != null && mockResult.ExceptionResult != null)
                    {
                        throw mockResult.ExceptionResult.Exception;
                    }
                    else
                    {
                        throw new NotSupportedException(string.Format("Mock SqlConnection does not know how to handle query: '{0}'", commandKey));
                    }
                }
            }

            return(mockResult.DataSetResult.DataSet.CreateDataReader());
        }
        /// <summary>
        /// Save the mock results to a file.
        /// </summary>
        /// <param name="mockResult">The results to save</param>
        private void SaveMockResult(MockQueryResult mockResult)
        {
            string[] parts = mockResult.MockId.Split(new char[] { '.' });

            string fileName = Path.Combine(this.settings.OutputPath, parts[0] + ".xml");

            MockQueryResultSet mockResultSet = null;

            if (File.Exists(fileName))
            {
                string fileText = File.ReadAllText(fileName).Trim();

                if (fileText != String.Empty)
                {
                    using (Stream stream = new MemoryStream(System.Text.UnicodeEncoding.UTF8.GetBytes(fileText)))
                    {
                        mockResultSet = MockQueryResultSet.Deserialize(stream);
                    }
                }
            }

            if (mockResultSet == null)
            {
                mockResultSet = new MockQueryResultSet();
            }

            string mockResultKey = NormalizeCommandText(mockResult.CommandText);

            int matchIdx = -1;

            for (int idx = 0; idx < mockResultSet.CommandResults.Count; idx++)
            {
                MockQueryResult currentResult = mockResultSet.CommandResults[idx];

                if (NormalizeCommandText(currentResult.CommandText) == mockResultKey &&
                    currentResult.DatabaseName == mockResult.DatabaseName &&
                    currentResult.MockId == mockResult.MockId)
                {
                    matchIdx = idx;
                    break;
                }
            }

            if (matchIdx >= 0)
            {
                mockResultSet.CommandResults[matchIdx] = mockResult;
            }
            else
            {
                mockResultSet.CommandResults.Add(mockResult);
            }

            using (Stream stream = File.Open(fileName, FileMode.Create, FileAccess.Write))
            {
                MockQueryResultSet.Serialize(stream, mockResultSet);
            }

            AddMockResult(mockResult);
        }
        /// <summary>
        /// Record the result of calling Execute database data reader
        /// </summary>
        /// <returns>The mock query results</returns>
        private MockQueryResult RecordExecuteDbDataReader()
        {
            MockQueryResult mockResult = new MockQueryResult();

            mockResult.CommandText  = this.GetCommandKey();
            mockResult.DatabaseName = this.DbConnection.Database;
            mockResult.MockId       = this.settings.MockId;

            try
            {
                using (SqlConnection connection = this.CreateSqlConnection())
                {
                    connection.Open();

                    SqlCommand cmd = connection.CreateCommand();
                    cmd.CommandTimeout = 120;
                    cmd.CommandType    = this.CommandType;
                    cmd.CommandText    = this.CommandText;

                    foreach (DbParameter param in this.Parameters)
                    {
                        SqlParameter sqlParam = new SqlParameter(param.ParameterName, param.DbType);
                        if (param.Value == null)
                        {
                            sqlParam.Value = DBNull.Value;
                        }
                        else
                        {
                            sqlParam.Value = param.Value;
                        }
                        cmd.Parameters.Add(sqlParam);
                    }

                    DataSet dataSet = new DataSet();

                    SqlDataAdapter adapter = new SqlDataAdapter(cmd);
                    adapter.Fill(dataSet);

                    mockResult.DataSetResult = new MockDataSet(dataSet);
                }

                this.SaveMockResult(mockResult);

                return(mockResult);
            }
            catch (SqlException e)
            {
                // Record any exceptions generated
                mockResult.ExceptionResult = new MockException(e);
                this.SaveMockResult(mockResult);

                // Rethrow exception to caller
                throw;
            }
        }
        /// <summary>
        /// Adds a mock result to this list of results.
        /// </summary>
        /// <param name="mockResult">the mock result to add</param>
        private static void AddMockResult(MockQueryResult mockResult)
        {
            List <MockQueryResult> list;

            string key = NormalizeCommandText(mockResult.CommandText);

            if (!mockResults.TryGetValue(key, out list))
            {
                list = new List <MockQueryResult>();
                mockResults.Add(key, list);
            }

            list.Add(mockResult);
        }
        /// <summary>
        /// Executes a scalar command against the mock framework
        /// </summary>
        /// <returns>The scalar result of the query, or null if none exist</returns>
        public override object ExecuteScalar()
        {
            Assert.IsTrue((this.Connection.State & ConnectionState.Open) == ConnectionState.Open, "Connection has to be opened when executing command");

            MockQueryResult mockResult = null;

            if (this.settings.RecordingMode)
            {
                mockResult = this.RecordExecuteScalar();
            }
            else
            {
                string commandKey = this.GetCommandKey();
                FindMockResult(this.settings.MockId, this.Connection.Database, commandKey, this.settings.IsolatedQueries);
            }

            return(mockResult != null ? mockResult.ScalarResult : null);
        }
        /// <summary>
        /// Adds a mock result to this list of results.
        /// </summary>
        /// <param name="mockResult">the mock result to add</param>
        private static void AddMockResult(MockQueryResult mockResult)
        {
            List<MockQueryResult> list;

            string key = NormalizeCommandText(mockResult.CommandText);
            if (!mockResults.TryGetValue(key, out list))
            {
                list = new List<MockQueryResult>();
                mockResults.Add(key, list);
            }

            list.Add(mockResult);
        }
        /// <summary>
        /// Save the mock results to a file.
        /// </summary>
        /// <param name="mockResult">The results to save</param>
        private void SaveMockResult(MockQueryResult mockResult)
        {
            string[] parts = mockResult.MockId.Split(new char[] { '.' });

            string fileName = Path.Combine(this.settings.OutputPath, parts[0] + ".xml");

            MockQueryResultSet mockResultSet = null;
            if (File.Exists(fileName))
            {
                string fileText = File.ReadAllText(fileName).Trim();

                if (fileText != String.Empty)
                {
                    using (Stream stream = new MemoryStream(System.Text.UnicodeEncoding.UTF8.GetBytes(fileText)))
                    {
                        mockResultSet = MockQueryResultSet.Deserialize(stream);
                    }
                }
            }

            if (mockResultSet == null)
            {
                mockResultSet = new MockQueryResultSet();
            }

            string mockResultKey = NormalizeCommandText(mockResult.CommandText);

            int matchIdx = -1;
            for (int idx = 0; idx < mockResultSet.CommandResults.Count; idx++)
            {
                MockQueryResult currentResult = mockResultSet.CommandResults[idx];

                if (NormalizeCommandText(currentResult.CommandText) == mockResultKey &&
                    currentResult.DatabaseName == mockResult.DatabaseName &&
                    currentResult.MockId == mockResult.MockId)
                {
                    matchIdx = idx;
                    break;
                }
            }

            if (matchIdx >= 0)
            {
                mockResultSet.CommandResults[matchIdx] = mockResult;
            }
            else
            {
                mockResultSet.CommandResults.Add(mockResult);
            }

            using (Stream stream = File.Open(fileName, FileMode.Create, FileAccess.Write))
            {
                MockQueryResultSet.Serialize(stream, mockResultSet);
            }

            AddMockResult(mockResult);
        }
        /// <summary>
        /// Record the result of calling Execute database data reader
        /// </summary>
        /// <returns>The mock query results</returns>
        private MockQueryResult RecordExecuteDbDataReader()
        {
            MockQueryResult mockResult = new MockQueryResult();

            mockResult.CommandText = this.GetCommandKey();
            mockResult.DatabaseName = this.DbConnection.Database;
            mockResult.MockId = this.settings.MockId;

            try
            {
                using (SqlConnection connection = this.CreateSqlConnection())
                {
                    connection.Open();

                    SqlCommand cmd = connection.CreateCommand();
                    cmd.CommandTimeout = 120;
                    cmd.CommandType = this.CommandType;
                    cmd.CommandText = this.CommandText;

                    foreach (DbParameter param in this.Parameters)
                    {
                        SqlParameter sqlParam = new SqlParameter(param.ParameterName, param.DbType);
                        if (param.Value == null)
                        {
                            sqlParam.Value = DBNull.Value;
                        }
                        else
                        {
                            sqlParam.Value = param.Value;
                        }
                        cmd.Parameters.Add(sqlParam);
                    }

                    DataSet dataSet = new DataSet();

                    SqlDataAdapter adapter = new SqlDataAdapter(cmd);
                    adapter.Fill(dataSet);

                    mockResult.DataSetResult = new MockDataSet(dataSet);
                }

                this.SaveMockResult(mockResult);

                return mockResult;
            }
            catch (SqlException e)
            {
                // Record any exceptions generated
                mockResult.ExceptionResult = new MockException(e);
                this.SaveMockResult(mockResult);

                // Rethrow exception to caller
                throw;
            }
        }
        /// <summary>
        /// Records the results of calling execute scalar on the command
        /// </summary>
        /// <returns>The result of executing the command</returns>
        private MockQueryResult RecordExecuteScalar()
        {
            MockQueryResult mockResult = new MockQueryResult();

            using (SqlConnection connection = this.CreateSqlConnection())
            {
                connection.Open();

                SqlCommand cmd = connection.CreateCommand();
                cmd.CommandTimeout = 120;
                cmd.CommandType = this.CommandType;
                cmd.CommandText = this.CommandText;

                foreach (DbParameter param in this.Parameters)
                {
                    SqlParameter sqlParam = new SqlParameter(param.ParameterName, param.DbType);
                    sqlParam.Value = param.Value;
                    cmd.Parameters.Add(sqlParam);
                }

                mockResult.ScalarResult = cmd.ExecuteScalar();

                mockResult.CommandText = this.GetCommandKey();
                mockResult.DatabaseName = this.DbConnection.Database;
                mockResult.MockId = this.settings.MockId;
            }

            this.SaveMockResult(mockResult);

            return mockResult;
        }