微软的SqlHelper做数据层(一)
2007-05-20 11:37

CreateCommand创建命令#region CreateCommand创建命令

/** <summary>
        /// 创建一个由存储过程提供的命令
        /// </summary>
        /// <remarks>
        /// e.g.:
        /// SqlCommand command = CreateCommand(conn, "AddCustomer", "CustomerID", "CustomerName");
        /// </remarks>
        /// <param name="connection">一个合法的连接</param>
        /// <param name="spName">存储过程名</param>
        /// <param name="sourceColumns">源列名称数组</param>
        /// <returns>一个合法的命令</returns>
        internal static SqlCommand CreateCommand(SqlConnection connection, string spName, params string[] sourceColumns)
        {
            if (connection == null) throw new ArgumentException("connection");
            if (spName == null || spName.Length == 0) throw new ArgumentException("spName");

//创建一个命令
            SqlCommand cmd = new SqlCommand(spName, connection);
            cmd.CommandType = CommandType.StoredProcedure;

//如果接受一个参数,则处理它
            if ((sourceColumns != null) && (sourceColumns.Length > 0))
            {
                //提取存储过程参数
                SqlParameter[] commandParameters = SqlHelperParameterCache.GetSpParameterSet(connection, spName);

//设置源列的名称
                for (int index = 0; index < sourceColumns.Length; index++)
                    commandParameters[index].SourceColumn = sourceColumns[index];

//将参数附加到命令上
                AttachParameters(cmd, commandParameters);
            }
            return cmd;
        }

#endregion

/** <summary>
        /// 这个方法将一个数组的值赋值到一个SqlParameter数组
        /// </summary>
        /// <param name="commandParameters">要被赋值的SqlParameter数组</param>
        /// <param name="parameterValues">一个包含参数值的object数组</param>
        private static void AssignParameterValues(SqlParameter[] commandParameters, object[] parameterValues)
        {
            if ((commandParameters == null) || parameterValues == null)
            {
                //如果没有数据则返回
                return;
            }

//参数的数量必须与值得数量匹配
            if (commandParameters.Length != parameterValues.Length)
            {
                throw new ArgumentException("参数的个数不能匹配参数值的个数");
            }

//迭代参数数组,把object数组的值赋给相应的参数
            for (int i = 0, j = commandParameters.Length; i < j; i++)
            {
                //如果数组的值继承自IDbDataParameter,这是赋给它的属性值
                if (parameterValues[i] is IDbDataParameter)
                {
                    IDbDataParameter paraInstance = (IDbDataParameter)parameterValues[i];
                    if (paraInstance.Value == null)
                    {
                        commandParameters[i].Value = DBNull.Value;
                    }
                    else
                    {
                        commandParameters[i].Value = paraInstance.Value;
                    }
                }
                else if (parameterValues[i] == null)
                {
                    commandParameters[i].Value = DBNull.Value;
                }
                else
                {
                    commandParameters[i].Value = parameterValues[i];
                }
            }
        }

//--上面的这个也不错,--其他的我也分析清楚了但是感觉一个晕为什么呢~~这个类的重载好多阿,- -不太喜欢故而不写出来- -

SqlHelperParameterCache- -一般就不要用了,浪费内存但是某些特殊情况不如,自动生成数据实体的时候- -瓦塞塞,好用级了,- -可以通过这家伙生成所有存储过程的实体,- -某些程序就是这么干的- -我们先来看看

/** <summary>
    /// SqlHelperParameterCache 提供一些函数用来发现存储过程的参数
    /// </summary>
    internal sealed class SqlHelperParameterCache
    {
        private methods, variables, and constructors#region private methods, variables, and constructors

//这个类仅仅提供静态方法,并使用一个私有的构造器来阻止创建一个实例化对象
        private SqlHelperParameterCache() { }

private static Hashtable paramCache = Hashtable.Synchronized(new Hashtable());

/** <summary>
        /// 在运行时发现存储过程
        /// </summary>
        /// <param name="connection">一个合法的连接对象</param>
        /// <param name="spName">存储过程名</param>
        /// <param name="includeReturnValueParameter">是否包含返回的参数</param>
        /// <returns>被发现的参数数组</returns>
        private static SqlParameter[] DiscoverSpParameterSet(SqlConnection connection, string spName, bool includeReturnValueParameter)
        {
            if (connection == null) throw new ArgumentNullException("connection");
            if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

SqlCommand cmd = new SqlCommand(spName, connection);
            cmd.CommandType = CommandType.StoredProcedure;

connection.Open();
            SqlCommandBuilder.DeriveParameters(cmd);
            connection.Close();

if (!includeReturnValueParameter)
            {
                cmd.Parameters.RemoveAt(0);
            }

SqlParameter[] discoveredParameters = new SqlParameter[cmd.Parameters.Count];

cmd.Parameters.CopyTo(discoveredParameters, 0);

// 将参数置为DBNull.Value
            foreach (SqlParameter discoveredParameter in discoveredParameters)
            {
                discoveredParameter.Value = DBNull.Value;
            }
            return discoveredParameters;
        }

/** <summary>
        /// 深度拷贝参数数组
        /// </summary>
        /// <param name="originalParameters"></param>
        /// <returns></returns>
        private static SqlParameter[] CloneParameters(SqlParameter[] originalParameters)
        {
            SqlParameter[] clonedParameters = new SqlParameter[originalParameters.Length];

for (int i = 0, j = originalParameters.Length; i < j; i++)
            {
                clonedParameters[i] = (SqlParameter)((ICloneable)originalParameters[i]).Clone();
            }

return clonedParameters;
        }

#endregion private methods, variables, and constructors

caching functions#region caching functions

/** <summary>
        /// 将参数数组添加到缓存
        /// </summary>
        /// <param name="connectionString">一个合法的连接字符串</param>
        /// <param name="commandText">命令文本</param>
        /// <param name="commandParameters">被缓存的参数数组</param>
        internal static void CacheParameterSet(string connectionString, string commandText, params SqlParameter[] commandParameters)
        {
            if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
            if (commandText == null || commandText.Length == 0) throw new ArgumentNullException("commandText");

string hashKey = connectionString + ":" + commandText;

paramCache[hashKey] = commandParameters;
        }

/** <summary>
        /// 从缓存中提取参数
        /// </summary>
        /// <param name="connectionString">一个合法的连接字符串</param>
        /// <param name="commandText">命令文本</param>
        /// <returns>参数数组</returns>
        internal static SqlParameter[] GetCachedParameterSet(string connectionString, string commandText)
        {
            if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
            if (commandText == null || commandText.Length == 0) throw new ArgumentNullException("commandText");

string hashKey = connectionString + ":" + commandText;

SqlParameter[] cachedParameters = paramCache[hashKey] as SqlParameter[];
            if (cachedParameters == null)
            {
                return null;
            }
            else
            {
                //为什么要进行克隆
                return CloneParameters(cachedParameters);
            }
        }

#endregion caching functions

Parameter Discovery Functions#region Parameter Discovery Functions

/** <summary>
        /// 获取存储过程的参数
        /// </summary>
        /// <remarks>
        /// 这个方法将查询数据库,并将其放置在缓存中
        /// </remarks>
        /// <param name="connectionString">一个合法的连接</param>
        /// <param name="spName">存储过程名</param>
        /// <returns>数组参数</returns>
        internal static SqlParameter[] GetSpParameterSet(string connectionString, string spName)
        {
            return GetSpParameterSet(connectionString, spName, false);
        }

/** <summary>
        /// 获取存储过程的参数
        /// </summary>
        /// <remarks>
        /// 这个方法将查询数据库,并将其放置在缓存中
        /// </remarks>
        /// <param name="connectionString">一个合法的连接</param>
        /// <param name="spName">存储过程名</param>
        /// <param name="includeReturnValueParameter">是否在结果中返回参数值</param>
        /// <returns>参数数组</returns>
        internal static SqlParameter[] GetSpParameterSet(string connectionString, string spName, bool includeReturnValueParameter)
        {
            if (connectionString == null || connectionString.Length == 0) throw new ArgumentNullException("connectionString");
            if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

using (SqlConnection connection = new SqlConnection(connectionString))
            {
                return GetSpParameterSetInternal(connection, spName, includeReturnValueParameter);
            }
        }

/** <summary>
        /// 获取存储过程的参数
        /// </summary>
        /// <remarks>
        /// 这个方法将查询数据库,并将其放置在缓存中
        /// </remarks>
        /// <param name="connection">一个合法的连接对象</param>
        /// <param name="spName">存储过程名</param>
        /// <returns>参数数组</returns>
        internal static SqlParameter[] GetSpParameterSet(SqlConnection connection, string spName)
        {
            return GetSpParameterSet(connection, spName, false);
        }

/** <summary>
        /// 获取存储过程的参数
        /// </summary>
        /// <remarks>
        /// 这个方法将查询数据库,并将其放置在缓存中
        /// </remarks>
        /// <param name="connection">一个合法的连接对象</param>
        /// <param name="spName">存储过程名</param>
        /// <param name="includeReturnValueParameter">是否在结果中返回参数值</param>
        /// <returns>参数数组</returns>
        internal static SqlParameter[] GetSpParameterSet(SqlConnection connection, string spName, bool includeReturnValueParameter)
        {
            if (connection == null) throw new ArgumentNullException("connection");
            using (SqlConnection clonedConnection = (SqlConnection)((ICloneable)connection).Clone())
            {
                return GetSpParameterSetInternal(clonedConnection, spName, includeReturnValueParameter);
            }
        }

/** <summary>
        /// 这个方法将查询数据库,并将其放置在缓存中
        /// </summary>
        /// <param name="connection">一个合法的连接对象</param>
        /// <param name="spName">存储过程名</param>
        /// <param name="includeReturnValueParameter">是否在结果中返回参数值</param>
        /// <returns>参数数组</returns>
        private static SqlParameter[] GetSpParameterSetInternal(SqlConnection connection, string spName, bool includeReturnValueParameter)
        {
            if (connection == null) throw new ArgumentNullException("connection");
            if (spName == null || spName.Length == 0) throw new ArgumentNullException("spName");

string hashKey = connection.ConnectionString + ":" + spName + (includeReturnValueParameter ? ":include ReturnValue Parameter" : "");

SqlParameter[] cachedParameters;

cachedParameters = paramCache[hashKey] as SqlParameter[];
            if (cachedParameters == null)
            {
                SqlParameter[] spParameters = DiscoverSpParameterSet(connection, spName, includeReturnValueParameter);
                paramCache[hashKey] = spParameters;
                cachedParameters = spParameters;
            }

return CloneParameters(cachedParameters);
        }

#endregion Parameter Discovery Functions

}

微软的SqlHelper做数据层(一)相关推荐

  1. 三层架构:表示层-业务逻辑-数据层

    三层架构:表示层-业务逻辑- 原文地址:三层架构:表示层-业务逻辑层-数据访问层  作者:灰烬 三层架构和MVC是两个东西. 非要相关的话: 三层架构中"表现层"的aspx页面对应 ...

  2. EF通用数据层封装类(支持读写分离,一主多从)

    浅谈orm 记得四年前在学校第一次接触到 Ling to Sql,那时候瞬间发现不用手写sql语句是多么的方便,后面慢慢的接触了许多orm框架,像 EF,Dapper,Hibernate,Servic ...

  3. 微软官方SQLHELPER类,很实用,中文注释

    微软官方SQLHELPER类,很实用,中文注释 找了好就终于找到个完整的中文注释的了,语法,结构都值得学习哦 using System; using System.Data; using System ...

  4. 黑客声称盗取微软GitHub账号500GB数据,网友:这些最终都会开源的

    点击上方"AI遇见机器学习",选择"星标"公众号 重磅干货,第一时间送达 十三 发自 凹非寺 量子位 报道 | 公众号 QbitAI 最近被黑客攻击.数据泄露的 ...

  5. V神建议使用BCH区块链用于以太坊“数据层”

    在以太坊社区论坛Ethresear.ch中,以太坊联合创始人Vitalik Buterin发布了一篇题为<BCH:以太坊的短期数据可用层?>的文章,他在文中提出了一个关于解决以太坊短期网络 ...

  6. 一步一步教你使用AgileEAS.NET基础类库进行应用开发-基础篇-基于接口驱动的数据层...

    系列回顾 在前面的文章中,我用了大量的篇幅对UDA及ORM的使用进行了讲解和演示,我们已经知道并熟悉的使用UDA和ORM构建简单的应用,AgileEAS.NET在应用的纵向结构上建议使用分层结构,提出 ...

  7. CYQ.Data 轻量数据层之路 V2.0 震撼惊世 支持多数据库/内置Aop(二十五)

    所有文章索引:CYQ.Data 轻量数据层之路 框架开源系列 索引 前言: 从V1.5发布到现在时隔20天了,终于发布2.0版本了,2.0系列版本由于引入多数据库支持,内部结构改动较大. 但是外面调用 ...

  8. mysql errno : 1146_MySQL_MySQL复制出错 Last_SQL_Errno:1146的解决方法,背景:我们在做数据迁移或者 - phpStudy...

    MySQL复制出错 Last_SQL_Errno:1146的解决方法 背景:我们在做数据迁移或者拆分的时候,使用Tablespace transcation 这种解决方案时,很有可能就会遇到 从库复制 ...

  9. 【类库】私房干货.Net数据层方法的封装

    [类库]私房干货.Net数据层方法的封装 作者:白宁超 时间:2016年3月5日22:51:47 摘要:继上篇<Oracle手边常用70则脚本知识汇总>文章的发表,引起很多朋友关注.便促使 ...

  10. 不加样本就能做数据增强?还能提效?

    数据增强早已被广泛应用在提升模型泛化能力上,通过"创造"额外的样本输入给模型使得模型更加鲁棒.近期又有隐式数据增强,不是通过直接创造样本来提高模型效果,那隐式数据增强究竟是怎么做的 ...

最新文章

  1. 二叉树的前序,中序,后序的递归、迭代实现
  2. pandas使用normalize函数将dataframe中的时间(time)数据列转化为日期(date)数据列(例如,从2019-12-25 11:30:00到2019-12-25)
  3. java编写限制密码_java – 用户’root’@’localhost’拒绝访问(使用密码:YES)
  4. Swift之extension的使用
  5. python创建文件对象_python基础教程:文件读写
  6. 开源 免费 java CMS - FreeCMS1.5-数据对象-job
  7. 如何接受上级指令_与上级沟通的技巧
  8. URI,URL的区别
  9. 数据库 关于权限管理系统的三种设计方法
  10. win10只有c盘怎么分区_win10系统硬盘怎么分区
  11. 在Mac上使用android studio调试android手机
  12. 创业者不能盲目的跟风,不然结局很凄凉
  13. 牵线搭桥,『桥接模式』
  14. java lru笔试题,2016年头条校招笔试(LRU算法)
  15. 从微信办公看信息泄露
  16. 查看创表语句 SHOW CREATE TABLE t_idcard
  17. 技术的真相 | 从AR口红试妆了解人工智能试妆技术
  18. Python实现桌面宠物
  19. 《跨语言文本相似性检测》第一周—前期调研
  20. mcgs组态软件中字体如果从左到右变化_在MCGS嵌入版组态软件中,数据对象有开关型、数值型、字符型、事件型和组对象五种类型。( )...

热门文章

  1. 关于在手机上注册Google账号
  2. 如何合并两个excel表格数据
  3. 全桥驱动IR系列参考设计及问题指南
  4. 【若依vue框架学习】4.获取登录用户信息(getInfo)
  5. JAVA POJ3233—矩阵幂序列问题
  6. Java中获取当前时间、昨天、三天前、一周前、一月前时间(2)
  7. 手写的计算机论文范文,手写2000论文格式模板_科技论文手写格式模板
  8. 计算机病毒与防治说课稿,计算机病毒与防治说课稿.doc
  9. 表格相对引用和绝对引用及相互切换(复制单元格函数公式保持不变)
  10. 全国省市json文件