加入收藏 | 设为首页 | 会员中心 | 我要投稿 站长网 (https://www.zhandada.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 站长学院 > Asp教程 > 正文

告别ADO.NET实现应用系统无缝切换的烦恼(总结篇)

发布时间:2021-07-11 01:11:10 所属栏目:Asp教程 来源:互联网
导读:说起ADO.NET,就扯上了数据库访问类库了,现在的每个项目的数据库访问类应该说都很强的了,经常就听到说我的我们的数据库访问类怎么怎么强大而且支持多数据库,


/// <summary>
/// 根据不同的数据库命令对象返回该类型数据库参数的前缀格式化字符串
/// </summary>
/// <param></param>
/// <returns></returns>
private string GetParameterFormat(DbCommand command)
{
if (!ParametersFormat.ContainsKey(command.GetType()))
{
this.Open();//读取参数前缀时需打开数据库连接
ParametersFormat.Add(
command.GetType(),
command.Connection.GetSchema("DataSourceInformation")
.Rows[0]["ParameterMarkerFormat"].ToString());
//conn.Close();在真正执行语句的时候去关闭,避免重复打开
}
return ParametersFormat[command.GetType()];
}


就是这个了 ParameterMarkerFormat,即参数标志符格式化,如连接oracle数据库则返回:{0},其它几个数据库返回@{0},惟独SQL SERVER数据库返回{0},到底是MS自己的东西,就是要返回跟别人不一样的东西,也就因为这个,这个类库里很遗憾不得不出现一个SqlCommand,就是上面贴出的构造函数里的初始化那ParametersFormat.Add(typeof(System.Data.SqlClient.SqlCommand), "@{0}");必须这样做下处理,另外包括GetParameterFormat方法里的判断,即不是SQL SERVER数据库时才去读参数前缀,如果是就直接返回@{0},有了这个格式化的前缀字符串,就好办了.那参数名称的赋值就可以类似这样了string.Format("@{0}", ParaName);
下面说说各通用的方法和调用,之前的sqlhelper.cs,oraclehelper.cs,xxhelper.cs中的执行方法大多都很多,有带参数执行的语句的方法,不带参数执行的语句的方法,带参数执行的方法体里面还要循环参数,这些都我都精简掉了,最终演变成了peacehelper.cs(开个玩笑).带参执行和不带参执行DML语句,其实是可以合并成一个方法,各个参数都是保存在数据库命令对象的参数集合中的,我们可以把创建好的命令对象返回给外部程序调用处,调用的地方要带参执行语句的话,就定义参数并赋值就行了,不带参执行的话就不用定义参数了,这么以来就只需要写一个方法就行了,而且执行带掺的语句时不用再循环参数集合了,因为在调用处定义参数时,该参数已经绑定都了DbCommand对象了.写一个返回给外部调用的数据库命令对象的方法,如下:

复制代码 代码如下:


/// <summary>
/// 抽象参数集合类型
/// </summary>
/// <returns></returns>
public DbParameterCollection GetParmCollection()
{
return cmd.Parameters;
}


添加参数的方法如下:

复制代码 代码如下:


/// <summary>
/// 添加参数
/// </summary>
/// <param>参数名称</param>
/// <param>参数数据类型</param>
/// <param>参数值</param>
/// <param>参数对象的集合</param>
public void AddParam(string ParaName, DbType SqlType, object ParaValue, DbParameterCollection ParaCollect)
{
//不允许将一个DbCommand对象的Parameters插入到另外一个DbCommand对象,那么多个参数的话可以加上下面一句判断
//如果已经存在至少一个对象时,再深层拷贝一个
if (ParaCollect.Count >= 1)
{
Para = (DbParameter)((ICloneable)ParaCollect[0]).Clone();
}
Para.ParameterName = string.Format(retParaformat, ParaName);
Para.DbType = SqlType;
if (ParaValue == null)
{
Para.Value = string.Empty;//DBNull.Value;
}
else
{
Para.Value = ParaValue;
}
ParaCollect.Add(Para);
}


上面有句判断,如果有多个参数会出异常,网上搜了下,注释就是网上的解释,不多说了,意思很清楚。这个方法里还有一点,如果DbType参数不要的话测试也是可以通过的,猜想如果不显示指定参数数据类型的话,是不是都默认为object类型?这样的话会不会涉及一个装拆箱的操作呢?但是开发人员在调用处添加参数,是不应该关心参数的数据类型才对,干脆数据类型参数不要了,改成如下方法了:

复制代码 代码如下:


public void AddParam(string ParaName, object ParaValue, DbParameterCollection ParaCollect)
{
if (ParaCollect.Count >= 1)
{
Para = (DbParameter)((ICloneable)ParaCollect[0]).Clone();
}
Para.ParameterName = string.Format(retParaformat, ParaName);//将参数格式化为具体的数据库参数格式
if (ParaValue == null)
{
Para.Value = string.Empty;
}
else
{
Para.Value = ParaValue;
}
ParaCollect.Add(Para);
}


为了兼容不同的数据库(主要是oracle变量特殊问题),添加参数的方法分两种,一种是普通带参执行的DML语句,一种是代参执行的存储过程。对于SQL SERVER数据库即使是存储过程
变量参数仍是@前缀,ORACLE存储过程又是什么前缀呢?很遗憾,ORACLE存储过程的参数变量是不需要任何前缀的,为了单独兼容这一点,对于不同数据库如果调用的存储过程有参数
的话,建议用下面的三个添加参数的方法:

复制代码 代码如下:

(编辑:站长网)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

热点阅读