void IResultWriter.BeforeExecuteReader(AsyncDataAdapterCommand asyncDataAdapterCommand)
        {
            _beforeExecuteReaderTimestamp = Stopwatch.GetTimestamp();
            ++_commandCount;

            var command    = asyncDataAdapterCommand.Command;
            var message    = $"Command[{_commandCount - 1}] executing from line {asyncDataAdapterCommand.LineIndex + 1}...\r\n{command.CommandText}";
            var parameters = command.Parameters;

            if (!parameters.IsNullOrEmpty())
            {
                message += "\r\n" + command.Parameters.ToLogString();
            }

            _addInfoMessage(InfoMessageFactory.Create(InfoMessageSeverity.Verbose, null, message));

            _query = asyncDataAdapterCommand.Query;
            if (_query != null)
            {
                _fileName    = asyncDataAdapterCommand.FileName;
                _parameters  = asyncDataAdapterCommand.Parameters;
                _commandText = asyncDataAdapterCommand.CommandText;
                _results     = new List <Result>();
            }
        }
        void IResultWriter.AfterCloseReader(int affectedRows)
        {
            var duration      = Stopwatch.GetTimestamp() - _beforeExecuteReaderTimestamp;
            var header        = StopwatchTimeSpan.ToString(duration, 3);
            var stringBuilder = new StringBuilder();

            stringBuilder.Append($"Command[{_commandCount - 1}] completed.");
            if (affectedRows >= 0)
            {
                stringBuilder.Append($" {affectedRows} row(s) affected.");
            }
            var message = stringBuilder.ToString();

            _addInfoMessage(InfoMessageFactory.Create(InfoMessageSeverity.Verbose, header, message));

            if (_query != null)
            {
                var directory = _fileName != null?Path.GetDirectoryName(_fileName) : Path.GetTempPath();

                var results = _query.Results.EmptyIfNull().Zip(_results, ToResult).ToReadOnlyList();
                var query   = new DbRequest(directory, _query.Name, _query.Using, _query.Namespace, _commandText, 0, _parameters, results);

                var queryBuilder     = new DbRequestBuilder(query);
                var csharpSourceCode = queryBuilder.Build();

                var path = Path.Combine(query.Directory, $"{query.Name}.generated.cs");
                File.WriteAllText(path, csharpSourceCode, Encoding.UTF8);

                _query       = null;
                _parameters  = null;
                _commandText = null;
                _results     = null;
            }
        }
        void IResultWriter.AfterCloseReader(int affectedRows)
        {
            var duration = Stopwatch.GetTimestamp() - _beforeExecuteReaderTimestamp;
            var now      = LocalTime.Default.Now;
            var affected = affectedRows >= 0
                ? $"{affectedRows} row(s) affected."
                : null;
            var message = $"Command[{_commandCount - 1}] completed in {StopwatchTimeSpan.ToString(duration, 3)} seconds. {affected}";

            _addInfoMessage(new InfoMessage(now, InfoMessageSeverity.Verbose, null, message));

            if (_query != null)
            {
                var directory = _fileName != null?Path.GetDirectoryName(_fileName) : Path.GetTempPath();

                var results = _query.Results.EmptyIfNull().Zip(_results, ToResult).ToReadOnlyCollection();
                var query   = new DbRequest(directory, _query.Name, _query.Using, _query.Namespace, _commandText, 0, _parameters, results);

                var queryBuilder     = new DbRequestBuilder(query);
                var csharpSourceCode = queryBuilder.Build();

                var path = Path.Combine(query.Directory, $"{query.Name}.generated.cs");
                File.WriteAllText(path, csharpSourceCode, Encoding.UTF8);

                _query       = null;
                _parameters  = null;
                _commandText = null;
                _results     = null;
            }
        }