MySqlHelper
的静态类,其中包含了一些用于执行 MySQL 数据库操作的方法。这些方法包括执行存储过程、插入、更新、删除操作以及执行数据库事务查询操作等。
该类中的方法主要有:
ExecuteNonQuery
方法:用于执行存储过程、插入、更新、删除操作,并返回受影响的行数。ExecuteScalar
方法:执行数据库事务查询操作或普通查询操作,返回结果集中位于第一行第一列的值。PrepareCommand
方法:执行数据库命令前的准备工作,设置命令对象的属性和参数。ToObject
方法:将MySqlDataReader
转换为指定类型的对象。- 其他辅助方法:用于处理参数、设置属性值、转换值等。
这些方法使用了异步编程模型 async/await
,并且在执行数据库操作后进行了相应的资源释放,以确保数据库连接得到正确关闭。
using MySql.Data.MySqlClient;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;namespace MSEBP.Kernel.DataCommon.DBHelper
{/// <summary>/// MySql数据库操作类/// </summary>public static class MySqlHelper{private static string _connectionString = MSEApplication.GetConfigValue("ConnectionStrings:ReadConn");/// <summary>/// 用于执行存储过程、插入、更新、删除/// </summary>/// <param name="cmdType"></param>/// <param name="cmdText"></param>/// <param name="cmdParms"></param>/// <returns></returns>public static async Task<int> ExecuteNonQuery(CommandType cmdType, string cmdText, object cmdParms){using (MySqlConnection conn = new MySqlConnection(_connectionString)){using (MySqlCommand cmd = conn.CreateCommand()){try{PrepareCommand(cmd, conn, null, cmdType, cmdText, cmdParms);int result = cmd.ExecuteNonQuery();cmd.Parameters.Clear();return await Task.FromResult(result);}catch (Exception ex){throw ex;}finally{if (conn.State == ConnectionState.Open){conn.Close();}}}}}/// <summary>/// 执行数据库事务查询操作,返回结果集中位于第一行第一列的Object类型的值/// </summary>/// <param name="trans">一个已存在的数据库事务对象</param>/// <param name="cmdType">命令类型</param>/// <param name="cmdText">MySql存储过程名称或PL/SQL命令</param>/// <param name="cmdParms">命令参数集合</param>/// <returns>当前事务查询操作返回的结果集中位于第一行第一列的Object类型的值</returns>public static async Task<T> ExecuteScalar<T>(MySqlTransaction trans, CommandType cmdType, string cmdText, object cmdParms){MySqlConnection conn;if (trans != null){conn = trans.Connection;if (conn == null)throw new ArgumentException("当前事务所在的数据库连接不存在");}else{conn = new MySqlConnection(_connectionString);}using (MySqlCommand cmd = conn.CreateCommand()){try{object result = null;PrepareCommand(cmd, conn, trans, cmdType, cmdText, cmdParms);result = cmd.ExecuteScalar();cmd.Parameters.Clear();return await Task.FromResult(ConvertTo<T>(result));}catch (Exception ex){throw ex;}finally{if (trans == null){if (conn.State == ConnectionState.Open){conn.Close();}}}}}/// <summary>/// 执行数据库查询操作,返回结果集中位于第一行第一列的Object类型的值/// </summary>/// <param name="cmdType">Command类型</param>/// <param name="cmdText">MySql存储过程名称或PL/SQL命令</param>/// <param name="cmdParms">命令参数集合</param>/// <returns>当前查询操作返回的结果集中位于第一行第一列的Object类型的值</returns>public static async Task<T> ExecuteScalar<T>(CommandType cmdType, string cmdText, object cmdParms){using (MySqlConnection conn = new MySqlConnection(_connectionString)){using (MySqlCommand cmd = conn.CreateCommand()){try{object result = null;PrepareCommand(cmd, conn, null, cmdType, cmdText, cmdParms);result = cmd.ExecuteScalar();cmd.Parameters.Clear();return await Task.FromResult(ConvertTo<T>(result));}catch (Exception ex){throw ex;}finally{if (conn.State == ConnectionState.Open){conn.Close();}}}}}/// <summary>/// 执行数据库命令前的准备工作/// </summary>/// <param name="cmd">Command对象</param>/// <param name="conn">数据库连接对象</param>/// <param name="trans">事务对象</param>/// <param name="cmdType">Command类型</param>/// <param name="cmdText">MySql存储过程名称或PL/SQL命令</param>/// <param name="cmdParms">命令参数集合</param>private static void PrepareCommand(MySqlCommand cmd, MySqlConnection conn, MySqlTransaction trans, CommandType cmdType, string cmdText, object cmdParms){if (conn?.State != ConnectionState.Open)conn.Open();cmd.Connection = conn;cmd.CommandText = cmdText;if (trans != null)cmd.Transaction = trans;cmd.CommandType = cmdType;cmd.CommandTimeout = 60 * 2;if (cmdParms != null){if (cmdParms is IDictionary<string, object> dict){foreach (var item in dict){cmd.Parameters.AddWithValue($"@{item.Key}", item.Value ?? DBNull.Value);}}else{PropertyInfo[] properties = cmdParms.GetType().GetProperties();foreach (PropertyInfo property in properties){object value = property.GetValue(cmdParms);cmd.Parameters.AddWithValue($"@{property.Name}", value ?? DBNull.Value);}}}}/// <summary>/// /// </summary>/// <param name="cmdParms"></param>/// <returns></returns>private static IEnumerable<MySqlParameter> GetParameters(object cmdParms){if (cmdParms is null)yield break;if (cmdParms is IDictionary<string, object> dict){foreach (var item in dict){yield return new MySqlParameter($"@{item.Key}", item.Value ?? DBNull.Value);}}else{var properties = cmdParms.GetType().GetProperties();foreach (var property in properties){var value = property.GetValue(cmdParms);yield return new MySqlParameter($"@{property.Name}", value ?? DBNull.Value);}}}/// <summary>/// reader转成类型数据/// </summary>/// <typeparam name="T"></typeparam>/// <param name="reader"></param>/// <returns></returns>public static T ToObject<T>(this MySqlDataReader reader){if (!reader.HasRows)return default(T);Type type = typeof(T);if (type.IsPrimitive || type == typeof(string) || type == typeof(decimal) || type == typeof(DateTime) || type == typeof(Guid) || type.IsEnum || type.IsArray){reader.Read(); // 移动到第一行object value = reader.GetValue(0);return value == DBNull.Value ? default(T) : ConvertTo<T>(value);}int columnCount = reader.FieldCount;var properties = type.GetProperties().Where(p => p.CanWrite);T obj = (T)Activator.CreateInstance(type);if (reader.Read()) // 读取第一行数据{foreach (var property in properties){int columnIndex = Enumerable.Range(0, columnCount).FirstOrDefault(i => string.Compare(reader.GetName(i), property.Name,StringComparison.OrdinalIgnoreCase) == 0);if (columnIndex >= 0){object value = reader.IsDBNull(columnIndex) ? null : reader.GetValue(columnIndex);if (value != DBNull.Value){if (property.PropertyType.IsEnum){value = Enum.Parse(property.PropertyType, value.ToString());}else{value = ConvertValue(value, property.PropertyType);}SetProperty(property, value, obj);}}}}reader.Dispose();reader.Close();return obj;}/// <summary>/// 设置值/// </summary>/// <param name="property"></param>/// <param name="value"></param>/// <param name="obj"></param>private static void SetProperty(PropertyInfo property, object value, object obj){if (value == null) return;if (property.PropertyType == typeof(Guid)){value = Guid.Parse(value.ToString());}else if (property.PropertyType.IsGenericType && property.PropertyType.GetGenericTypeDefinition() == typeof(Nullable<>)){Type underlyingType = Nullable.GetUnderlyingType(property.PropertyType);value = Convert.ChangeType(value, underlyingType);}else{value = Convert.ChangeType(value, property.PropertyType);}property.SetValue(obj, value, null);}/// <summary>/// 转换值/// </summary>/// <param name="value"></param>/// <param name="type"></param>/// <returns></returns>private static object ConvertValue(object value, Type type){if (type == typeof(Guid)){return Guid.Parse(value.ToString());}if (type.IsGenericType && type.GetGenericTypeDefinition() == typeof(Nullable<>)){Type underlyingType = Nullable.GetUnderlyingType(type);if (value == null){return null;}else{return Convert.ChangeType(value, underlyingType);}}return Convert.ChangeType(value, type);}/// <summary>/// 单值数据类型转换/// </summary>/// <typeparam name="T"></typeparam>/// <param name="value"></param>/// <returns></returns>private static T ConvertTo<T>(object value){if (value == null || value == DBNull.Value){return default(T);}Type targetType = typeof(T);if (targetType == typeof(Guid)){return (T)(object)Guid.Parse(value.ToString());}if (targetType.IsGenericType && targetType.GetGenericTypeDefinition() == typeof(Nullable<>)){targetType = Nullable.GetUnderlyingType(targetType);}return (T)Convert.ChangeType(value, targetType);}}
}