c# 操作mysql的帮助类

MySqlHelper 的静态类,其中包含了一些用于执行 MySQL 数据库操作的方法。这些方法包括执行存储过程、插入、更新、删除操作以及执行数据库事务查询操作等。

该类中的方法主要有:

  1. ExecuteNonQuery 方法:用于执行存储过程、插入、更新、删除操作,并返回受影响的行数。
  2. ExecuteScalar 方法:执行数据库事务查询操作或普通查询操作,返回结果集中位于第一行第一列的值。
  3. PrepareCommand 方法:执行数据库命令前的准备工作,设置命令对象的属性和参数。
  4. ToObject 方法:将 MySqlDataReader 转换为指定类型的对象。
  5. 其他辅助方法:用于处理参数、设置属性值、转换值等。

这些方法使用了异步编程模型 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);
        }

    }
}
相关推荐
StringerChen4 分钟前
Qt ui提升窗口的头文件找不到
开发语言·qt
数据小爬虫@10 分钟前
如何利用PHP爬虫获取速卖通(AliExpress)商品评论
开发语言·爬虫·php
yngsqq1 小时前
cad c# 二次开发 ——动态加载dll 文件制作(loada netloadx)
c#
java1234_小锋1 小时前
MyBatis如何处理延迟加载?
java·开发语言
FeboReigns1 小时前
C++简明教程(10)(初识类)
c语言·开发语言·c++
学前端的小朱1 小时前
处理字体图标、js、html及其他资源
开发语言·javascript·webpack·html·打包工具
摇光932 小时前
js高阶-async与事件循环
开发语言·javascript·事件循环·宏任务·微任务
沐泽Mu2 小时前
嵌入式学习-QT-Day09
开发语言·qt·学习
小猿_002 小时前
C语言实现顺序表详解
c语言·开发语言
KELLENSHAW3 小时前
MySQL45讲 第三十七讲 什么时候会使用内部临时表?——阅读总结
数据库·mysql