铭轩同学

铭轩,为自己代言!

  博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
using System;
using System.Collections;
using System.Collections.Generic;
using System.Configuration;
using System.Data;
using System.Data.SqlClient;
using System.Reflection;
using System.Threading;
namespace Common
{
    public enum AutoRollback
    {
        /// <summary>
        /// 手动回滚
        /// </summary>
        None,

        /// <summary>
        /// 除查询语句以外回滚
        /// </summary>
        ExceptQuery,

        /// <summary>
        /// 任何情况下回滚
        /// </summary>
        Always,
    }

    public class SqlDbContext : IDisposable
    {
        public AutoRollback AutoRollback { get; private set; }
        private string connectionString = ConfigurationManager.ConnectionStrings["conn"].ConnectionString;
        public string ConnectionString { get { return connectionString; } }

        public SqlConnection Connection { get; private set; }
        public SqlTransaction Transaction { get; private set; }

        public SqlDbContext(AutoRollback auto = AutoRollback.ExceptQuery) :
            this(ConfigurationManager.ConnectionStrings["conn"].ConnectionString, auto)
        {
        }

        public SqlDbContext(string connectionString, AutoRollback auto)
        {
            this.Connection = new SqlConnection(connectionString);
            this.AutoRollback = auto;
        }

        public void Dispose()
        {
            this.EndTrans();
            this.Close();

            if (this.Connection != null)
                this.Connection.Dispose();

            this.Connection = null;
            this.Transaction = null;
        }

        #region Transaction
        /// <summary>
        /// 开启事务
        /// </summary>
        public void BeginTrans()
        {
            if (this.Transaction != null)
                this.Transaction.Dispose();
            this.Open();
            this.Transaction = this.Connection.BeginTransaction();
        }

        /// <summary>
        /// 提交事务
        /// </summary>
        public void CommitTrans()
        {
            if (this.Transaction != null)
                this.Transaction.Commit();
        }

        /// <summary>
        /// 回滚
        /// </summary>
        public void RollbackTrans()
        {
            if (this.Transaction != null)
                this.Transaction.Rollback();
        }

        /// <summary>
        /// 结束事务,释放资源
        /// </summary>
        public void EndTrans()
        {
            if (this.Transaction != null)
                this.Transaction.Dispose();
            this.Transaction = null;
        }
        #endregion

        #region Exec Command

        #region 执行sql脚本块
        /// <summary>
        /// 执行Sql脚本块
        /// </summary>
        /// <param name="dbType">0为access,1为sqlserver</param>
        /// <param name="connectionString">数据库连接</param>
        /// <param name="pathToScriptFile">脚本路径,物理路径</param>
        /// <returns></returns>
        public bool Go(string strSql, CommandType commandType = CommandType.Text)
        {


            this.Open();

            try
            {
                using (SqlCommand cmd = new SqlCommand()
                {
                    CommandText = strSql,
                    CommandType = commandType,
                    Connection = this.Connection,
                })
                {
                    if (this.Transaction != null)
                        cmd.Transaction = this.Transaction;

                    foreach (string Sql in SqlList(strSql))
                    {
                        cmd.CommandText = Sql;
                        cmd.ExecuteNonQuery();
                    }
                }
                return true;
            }
            catch
            {
                if (this.AutoRollback != AutoRollback.None)
                    this.RollbackTrans();
                throw;
            }
        }
        private static string[] SqlList(string StrSql)
        {
            string[] _strList = StrSql.Split(new string[] { "GO" }, StringSplitOptions.RemoveEmptyEntries);
            return _strList;
        }
        #endregion
        /// <summary>
        /// 执行SQL语句, 此方法用于插入、更新操作
        /// 返回受影响的行数
        /// </summary>
        /// <param name="text">SQL执行语句</param>
        /// <param name="commandType">语句类型</param>
        /// <param name="args">语句参数</param>
        /// <returns>返回受影响的行数</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2100:检查 SQL 查询是否存在安全漏洞")]
        public int Execute(
            string text,
            CommandType commandType = CommandType.Text,
            params SqlParameter[] args)
        {
            this.Open();

            try
            {
                using (SqlCommand cmd = new SqlCommand()
                {
                    CommandText = text,
                    CommandType = commandType,
                    Connection = this.Connection,
                })
                {
                    if (this.Transaction != null)
                        cmd.Transaction = this.Transaction;

                    AddParameterToCommand(cmd, args);
                    return cmd.ExecuteNonQuery();
                }

            }
            catch
            {
                if (this.AutoRollback != AutoRollback.None)
                    this.RollbackTrans();
                throw;
            }
        }


        /// <summary>
        /// SqlBulkCopy 大批量数据插入
        /// </summary>
        /// <param name="table">内存表 Datatable</param>
        /// <param name="destinationTableName">服务器上表的名称</param>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2100:检查 SQL 查询是否存在安全漏洞")]
        public void ExecuteBulkCopy(DataTable table,
            string destinationTableName
        )
        {
            this.BeginTrans();
            try
            {
                using (SqlBulkCopy copy = new SqlBulkCopy(Connection, SqlBulkCopyOptions.Default, this.Transaction))
                {
                    copy.DestinationTableName = destinationTableName;
                    for (int i = 0; i < table.Columns.Count; i++)
                    {
                        copy.ColumnMappings.Add(table.Columns[i].ColumnName, table.Columns[i].ColumnName);
                    }
                    copy.WriteToServer(table);
                    this.CommitTrans();
                }
            }
            catch
            {
                if (this.AutoRollback != AutoRollback.None)
                    this.RollbackTrans();
                throw;
            }
        }


        /// <summary>
        /// 执行SQL语句,并返回查询结果的第一行第一列的值要返回什么样的值,就T 里面写入什么类型
        /// </summary>
        /// <typeparam name="T">返回结果类型</typeparam>
        /// <param name="query">SQL语句</param>
        /// <param name="commandType">语句类型</param>
        /// <param name="args">语句参数</param>
        /// <returns>返回查询结果的第一行第一列的值</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2100:检查 SQL 查询是否存在安全漏洞")]
        public T ExecuteScalar<T>(
            string query,
            CommandType commandType = CommandType.Text,
            params SqlParameter[] args)
        {
            this.Open();

            try
            {
                using (SqlCommand cmd = new SqlCommand()
                {
                    CommandText = query,
                    CommandType = commandType,
                    Connection = this.Connection,
                })
                {
                    if (this.Transaction != null)
                        cmd.Transaction = this.Transaction;

                    AddParameterToCommand(cmd, args);
                    object obj = cmd.ExecuteScalar();
                    if (obj == null || obj == DBNull.Value)
                        return default(T);
                    return (T)obj;
                }
            }
            catch
            {
                if (this.AutoRollback != AutoRollback.None)
                    this.RollbackTrans();
                throw;
            }
        }

        /// <summary>
        /// 执行SQL语句,并返回查询结果的第一行第一列的值
        /// </summary>
        /// <typeparam name="T">返回结果类型</typeparam>
        /// <param name="query">SQL语句</param>
        /// <param name="commandType">语句类型</param>
        /// <param name="args">语句参数</param>
        /// <returns>返回查询结果的第一行第一列的值</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2100:检查 SQL 查询是否存在安全漏洞")]
        public int ExecuteScalar(
            string query,
            CommandType commandType = CommandType.Text,
            params SqlParameter[] args)
        {
            this.Open();

            try
            {
                using (SqlCommand cmd = new SqlCommand()
                {
                    CommandText = query,
                    CommandType = commandType,
                    Connection = this.Connection,
                })
                {
                    if (this.Transaction != null)
                        cmd.Transaction = this.Transaction;

                    AddParameterToCommand(cmd, args);
                    object obj = cmd.ExecuteScalar();
                    return Convert.ToInt32(obj);
                }
            }
            catch
            {
                if (this.AutoRollback != AutoRollback.None)
                    this.RollbackTrans();
                throw;
            }
        }

        /// <summary>
        /// 执行SQL语句,并返回查询结果的实体类集合
        /// 实体类的属性需包含查询结果的表头
        /// </summary>
        /// <typeparam name="T">查询结果的实体类</typeparam>
        /// <param name="query">SQL语句</param>
        /// <param name="commandType">语句类型</param>
        /// <param name="args">语句参数</param>
        /// <returns>返回结果的实体类集合</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2100:检查 SQL 查询是否存在安全漏洞")]
        public List<T> Query<T>(
            string query,
            CommandType commandType = CommandType.Text,
            params SqlParameter[] args)
            where T : new()
        {
            this.Open();

            try
            {
                using (SqlCommand cmd = new SqlCommand()
                {
                    CommandText = query,
                    CommandType = commandType,
                    Connection = this.Connection,
                })
                {
                    if (this.Transaction != null)
                        cmd.Transaction = this.Transaction;

                    AddParameterToCommand(cmd, args);
                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        List<T> result = new List<T>();
                        var columns = GetColumns<T>(reader);
                        while (reader.Read())
                        {
                            T obj = CreateObject<T>(reader, columns);
                            result.Add(obj);
                        }
                        return result;
                    }
                }
            }
            catch
            {
                if (AutoRollback == AutoRollback.Always)
                    this.RollbackTrans();
                throw;
            }
        }


        /// <summary>
        /// 执行SQL语句,返回 SqlDataReader
        /// </summary>
        /// <param name="query">SQL语句</param>
        /// <param name="commandType">语句类型</param>
        /// <param name="args">语句参数</param>
        /// <returns>SqlDataReader</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2100:检查 SQL 查询是否存在安全漏洞")]
        public SqlDataReader GetDataReader(
            string query,
            CommandType commandType = CommandType.Text,
            params SqlParameter[] args)
        {
            this.Open();

            try
            {
                using (SqlCommand cmd = new SqlCommand()
                {
                    CommandText = query,
                    CommandType = commandType,
                    Connection = this.Connection,
                })
                {
                    if (this.Transaction != null)
                        cmd.Transaction = this.Transaction;

                    AddParameterToCommand(cmd, args);
                    return cmd.ExecuteReader();
                }
            }
            catch
            {
                if (AutoRollback == AutoRollback.Always)
                    this.RollbackTrans();
                throw;
            }
        }

        /// <summary>
        /// 执行SQL语句,以DataTable对象作为结果返回查询结果
        /// </summary>
        /// <param name="query">SQL语句</param>
        /// <param name="commandType">语句类型</param>
        /// <param name="args">语句参数</param>
        /// <returns>DataTable对象</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2100:检查 SQL 查询是否存在安全漏洞")]
        public DataTable QueryDT(
            string query,
            CommandType commandType = CommandType.Text,
            params SqlParameter[] args)
        {
            this.Open();
            try
            {
                using (SqlCommand cmd = new SqlCommand()
                {
                    CommandText = query,
                    CommandType = commandType,
                    Connection = this.Connection,
                })
                {
                    if (this.Transaction != null)
                        cmd.Transaction = this.Transaction;

                    AddParameterToCommand(cmd, args);
                    DataTable result = new DataTable();
                    using (SqlDataAdapter ad = new SqlDataAdapter())
                    {
                        ad.SelectCommand = cmd;
                        ad.Fill(result);
                        return result;
                    }
                }
            }
            catch
            {
                if (AutoRollback == AutoRollback.Always)
                    this.RollbackTrans();
                throw;
            }
        }

        /// <summary>
        /// 执行SQL语句,并返回查询结果的第一个对象, 如果没有查询结果则为NULL
        /// 实体类的属性需包含查询结果的表头
        /// </summary>
        /// <typeparam name="T">查询结果的实体类</typeparam>
        /// <param name="query">SQL语句</param>
        /// <param name="commandType">语句类型</param>
        /// <param name="args">语句参数</param>
        /// <returns>查询结果的第一个对象,如果没有查询结果则为NULL</returns>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Security", "CA2100:检查 SQL 查询是否存在安全漏洞")]
        public T FirstOrDefault<T>(
            string query,
            CommandType commandType = CommandType.Text,
            params SqlParameter[] args)
            where T : new()
        {
            this.Open();

            try
            {
                using (SqlCommand cmd = new SqlCommand()
                {
                    CommandText = query,
                    CommandType = commandType,
                    Connection = this.Connection,
                })
                {
                    if (this.Transaction != null)
                        cmd.Transaction = this.Transaction;

                    AddParameterToCommand(cmd, args);

                    using (SqlDataReader reader = cmd.ExecuteReader())
                    {
                        if (reader.HasRows)
                        {
                            var columns = GetColumns<T>(reader);
                            reader.Read();
                            return CreateObject<T>(reader, columns);
                        }

                        return default(T);
                    }
                }
            }
            catch
            {
                if (AutoRollback == AutoRollback.Always)
                    this.RollbackTrans();
                throw;
            }
        }
        #endregion

        #region HelperMethods
        public void Open()
        {
            if (this.Connection != null &&
                this.Connection.State != ConnectionState.Open)
                this.Connection.Open();
        }

        public void Close()
        {
            if (this.Connection != null)
                this.Connection.Close();
        }

        public SqlCommand CreateCommand()
        {
            SqlCommand cmd = new SqlCommand();
            cmd.Connection = this.Connection;
            if (this.Transaction != null)
                cmd.Transaction = this.Transaction;

            return cmd;
        }

        public static void AddParameterToCommand(SqlCommand cmd, SqlParameter[] args)
        {
            if (args != null && args.Length > 0)
            {
                foreach (var arg in args)
                {
                    if (arg != null)
                    {
                        if (arg.IsNullable && arg.Value == null)
                        {
                            arg.Value = DBNull.Value;
                        }

                        cmd.Parameters.Add(arg);
                    }
                }
            }
        }

        private static PropertyInfo[] GetColumns<T>(SqlDataReader reader)
        {
            List<T> result = new List<T>();
            Type type = typeof(T);
            var columns = new List<PropertyInfo>(reader.FieldCount);
            var props = type.GetProperties();
            string name;

            for (int i = 0; i < reader.FieldCount; i++)
            {
                name = reader.GetName(i);
                for (int j = 0; j < props.Length; j++)
                {
                    if (props[j].Name.ToLower() == name.ToLower())
                    {
                        columns.Add(props[j]);
                        break;
                    }
                }
            }

            return columns.ToArray();
        }

        private static T CreateObject<T>(SqlDataReader reader, PropertyInfo[] columns) where T : new()
        {
            T result = Activator.CreateInstance<T>();
            for (int i = 0; i < columns.Length; i++)
            {
                columns[i].SetValue(result, reader[columns[i].Name] == DBNull.Value ? null : reader[columns[i].Name], null);
            }

            return result;
        }
        #endregion

    }
}

 

posted on 2014-05-15 17:37  铭轩同学  阅读(563)  评论(0编辑  收藏  举报