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);
}
}
}