/// <summary> /// 若使用【读写分离】,查询【从库】条件cmdText.StartsWith("SELECT "),否则查询【主库】 /// </summary> /// <param name="readerHander"></param> /// <param name="cmdType"></param> /// <param name="cmdText"></param> /// <param name="cmdParms"></param> public void ExecuteReader(Action <MySqlDataReader> readerHander, CommandType cmdType, string cmdText, params MySqlParameter[] cmdParms) { DateTime dt = DateTime.Now; string logtxt = ""; DateTime logtxt_dt = DateTime.Now; var pool = this.MasterPool; bool isSlave = false; //读写分离规则 if (this.SlavePools.Any() && cmdText.StartsWith("SELECT ", StringComparison.CurrentCultureIgnoreCase)) { var availables = slaveUnavailables == 0 ? //查从库 this.SlavePools : ( //查主库 slaveUnavailables == this.SlavePools.Count ? new List <MySqlConnectionPool>() : //查从库可用 this.SlavePools.Where(sp => sp.IsAvailable).ToList()); if (availables.Any()) { isSlave = true; pool = availables.Count == 1 ? availables[0] : availables[slaveRandom.Next(availables.Count)]; } } Object <MySqlConnection> conn = null; var pc = PrepareCommand(cmdType, cmdText, cmdParms, ref logtxt); if (IsTracePerformance) { logtxt += $"PrepareCommand: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; } Exception ex = null; try { if (IsTracePerformance) { logtxt_dt = DateTime.Now; } if (isSlave) { //从库查询切换,恢复 bool isSlaveFail = false; try { if (pc.cmd.Connection == null) { pc.cmd.Connection = (conn = pool.Get()).Value; } //if (slaveRandom.Next(100) % 2 == 0) throw new Exception("测试从库抛出异常"); } catch { isSlaveFail = true; } if (isSlaveFail) { if (conn != null) { if (IsTracePerformance) { logtxt_dt = DateTime.Now; } pool.Return(conn, ex); if (IsTracePerformance) { logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms"; } } LoggerException(pool, pc.cmd, new Exception($"连接失败,准备切换其他可用服务器"), dt, logtxt, false); pc.cmd.Parameters.Clear(); ExecuteReader(readerHander, cmdType, cmdText, cmdParms); return; } } else { //主库查询 if (pc.cmd.Connection == null) { pc.cmd.Connection = (conn = pool.Get()).Value; } } if (IsTracePerformance) { logtxt += $"Open: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; logtxt_dt = DateTime.Now; } using (MySqlDataReader dr = pc.cmd.ExecuteReader()) { if (IsTracePerformance) { logtxt += $"ExecuteReader: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; } while (true) { if (IsTracePerformance) { logtxt_dt = DateTime.Now; } bool isread = dr.Read(); if (IsTracePerformance) { logtxt += $" dr.Read: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; } if (isread == false) { break; } if (readerHander != null) { object[] values = null; if (IsTracePerformance) { logtxt_dt = DateTime.Now; values = new object[dr.FieldCount]; dr.GetValues(values); logtxt += $" dr.GetValues: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; logtxt_dt = DateTime.Now; } readerHander(dr); if (IsTracePerformance) { logtxt += $" readerHander: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms ({string.Join(",", values)})\r\n"; } } } if (IsTracePerformance) { logtxt_dt = DateTime.Now; } dr.Close(); } if (IsTracePerformance) { logtxt += $"ExecuteReader_dispose: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms\r\n"; } } catch (Exception ex2) { ex = ex2; } if (conn != null) { if (IsTracePerformance) { logtxt_dt = DateTime.Now; } pool.Return(conn, ex); if (IsTracePerformance) { logtxt += $"ReleaseConnection: {DateTime.Now.Subtract(logtxt_dt).TotalMilliseconds}ms Total: {DateTime.Now.Subtract(dt).TotalMilliseconds}ms"; } } LoggerException(pool, pc.cmd, ex, dt, logtxt); pc.cmd.Parameters.Clear(); }
/// <summary> /// DataReader格式转换成DataTable /// </summary> /// <param name="DataReader">OleDbDataReader</param> private DataTable GetConvertDataReaderToDataTable(MySqlDataReader reader) { DataTable objDataTable = new DataTable("TmpDataTable"); int intCounter; try { //获取当前行中的列数; int intFieldCount = reader.FieldCount; for (intCounter = 0; intCounter <= intFieldCount - 1; intCounter++) { objDataTable.Columns.Add(reader.GetName(intCounter), reader.GetFieldType(intCounter)); } //populate datatable objDataTable.BeginLoadData(); //object[] objValues = new object[intFieldCount -1]; object[] objValues = new object[intFieldCount]; while (reader.Read()) { reader.GetValues(objValues); objDataTable.LoadDataRow(objValues, true); } reader.Close(); objDataTable.EndLoadData(); return objDataTable; } catch (MySqlException ex) { throw ex; } }
/// <summary> /// Constructs an instance of this class. /// </summary> /// <param name="command">Command these results are for.</param> /// <param name="reader">Data reader to extract results with.</param> public DBResults(MySqlCommand command, MySqlDataReader reader) { m_rowsAffected = reader.RecordsAffected; m_lastInsertID = command.LastInsertedId; if (reader.HasRows == true) { m_rowsAffected = 0; // Read in each row. while (reader.Read()) { // Make a new row instance to hold information about this row. DBRow row = new DBRow(); // Get all values. object[] values = new object[reader.FieldCount]; reader.GetValues(values); // Enter values into array based on column names. for (int i = 0; i < reader.FieldCount; i++) { string name = reader.GetName(i); row[name] = values[i] is System.DBNull ? null : values[i]; } // Insert into rows array. if (m_rowsAffected >= m_rows.Length) { DBRow[] newArray = new DBRow[m_rows.Length * 2]; Array.Copy(m_rows, newArray, m_rows.Length); m_rows = newArray; } m_rows[m_rowsAffected++] = row; } } }