/// <summary>
        /// sync execute reader
        /// </summary>
        /// <returns></returns>
        internal MySqlDataReader InternalExecuteReader()
        {
            if (!_isPreparedStmt)
            {
                _query = new Query(this.Connection.Conn, _sqlStringTemplate, Parameters);
            }
            var reader = new MySqlQueryDataReader(_query);

            reader.StringConverter = this.StringConverter;
            _query.Execute(true, null);
            reader.WaitUntilFirstDataArrive();
            //
            //after execute in sync mode (this method)
            //reader will wait unit first result arrive
            return(reader);
        }
        /// <summary>
        /// async exec reader, notify the when reader is ready
        /// </summary>
        internal void InternalExecuteReader(Action <MySqlDataReader> readerReady)
        {
            if (!_isPreparedStmt)
            {
                _query = new Query(this.Connection.Conn, _sqlStringTemplate, Parameters);
            }
            var reader = new MySqlQueryDataReader(_query);

            reader.StringConverter = this.StringConverter;
            //in non bloking mode, set this
            reader.SetFirstDataArriveDelegate(dataReader =>
            {
                //data reader is ready
                //then start async read on each sub table
                readerReady(dataReader);
            });
            //after execute in asyn mode( this method)
            //reader just return, not block,
            //
            //and when the first data arrive,
            //in invoke dataReaderReader delegate
            _query.Execute(true, () => { });//send empty lambda for async
        }
        /// <summary>
        /// async exec, on each sub table
        /// </summary>
        internal void InternalExecuteSubTableReader(Action <MySqlDataReader> onEachSubTable)
        {
            if (!_isPreparedStmt)
            {
                _query = new Query(this.Connection.Conn, _sqlStringTemplate, Parameters);
            }
            var reader = new MySqlQueryDataReader(_query);

            reader.StringConverter = this.StringConverter;
            //in non bloking mode, set this
            reader.SetFirstDataArriveDelegate(dataReader =>
            {
                //data reader is ready
                //then start async read on each sub table
                dataReader.ReadSubTable(subt =>
                {
                    //table is ready for read***
                    //just read single value
                    var subtReader             = subt.CreateDataReader();
                    subtReader.StringConverter = this.StringConverter;
                    onEachSubTable(subtReader);

                    if (subt.IsLastTable)
                    {
                        //auto close reader
                        dataReader.InternalClose(() => { });//send empty lambda for async
                    }
                });
            });
            //after execute in asyn mode( this method)
            //reader just return, not block,
            //
            //and when the first data arrive,
            //in invoke dataReaderReader delegate
            _query.Execute(true, () => { });//send empty lambda for async
        }
        /// <summary>
        /// async exec, on each sub table
        /// </summary>
        internal void InternalExecuteSubTableReader(Action<MySqlDataReader> onEachSubTable)
        {
            if (!_isPreparedStmt)
            {
                _query = new Query(this.Connection.Conn, _sqlStringTemplate, Parameters);
            }
            var reader = new MySqlQueryDataReader(_query); 
            reader.StringConverter = this.StringConverter;
            //in non bloking mode, set this
            reader.SetFirstDataArriveDelegate(dataReader =>
            {
                //data reader is ready
                //then start async read on each sub table
                dataReader.ReadSubTable(subt =>
                {
                    //table is ready for read***
                    //just read single value 
                    var subtReader = subt.CreateDataReader(); 
                    subtReader.StringConverter = this.StringConverter; 
                    onEachSubTable(subtReader);

                    if (subt.IsLastTable)
                    {
                        //auto close reader 
                        dataReader.InternalClose(() => { });//send empty lambda for async  
                    }
                });
            });
            //after execute in asyn mode( this method)
            //reader just return, not block,
            //
            //and when the first data arrive,
            //in invoke dataReaderReader delegate
            _query.Execute(true, () => { });//send empty lambda for async  
        }
 /// <summary>
 /// async exec reader, notify the when reader is ready
 /// </summary>
 internal void InternalExecuteReader(Action<MySqlDataReader> readerReady)
 {
     if (!_isPreparedStmt)
     {
         _query = new Query(this.Connection.Conn, _sqlStringTemplate, Parameters);
     }
     var reader = new MySqlQueryDataReader(_query); 
     reader.StringConverter = this.StringConverter; 
     //in non bloking mode, set this
     reader.SetFirstDataArriveDelegate(dataReader =>
     {
         //data reader is ready
         //then start async read on each sub table
         readerReady(dataReader);
     });
     //after execute in asyn mode( this method)
     //reader just return, not block,
     //
     //and when the first data arrive,
     //in invoke dataReaderReader delegate
     _query.Execute(true, () => { });//send empty lambda for async  
 }
        /// <summary>
        /// sync execute reader
        /// </summary>
        /// <returns></returns>
        internal MySqlDataReader InternalExecuteReader()
        {
            if (!_isPreparedStmt)
            {
                _query = new Query(this.Connection.Conn, _sqlStringTemplate, Parameters);
            }
            var reader = new MySqlQueryDataReader(_query);

            reader.StringConverter = this.StringConverter;
            _query.Execute(true, null);
            reader.WaitUntilFirstDataArrive();
            //
            //after execute in sync mode (this method)
            //reader will wait unit first result arrive            
            return reader;
        }