使用DAAB3.1连接多种数据库(SqlServer,OleDB,ODBC)(原创)

 

由于项目需要适用于Sybase 9.1.2和Sql Server 2000的数据库,刚开始使用DAAB3.1的Odbc来操作数据库,但总觉得不是十分灵活,而且Odbc连接Sql Server 2000效率也不高; 再者,我也想项目能够提供对Oracle的支持 。感谢天行者的daab3.1使用笔记,这篇文章介绍了如何通过只修改配置文件而不改动代码的情况下实现数据库的转换。


<configSections>
<section name="daabProviders" type="GotDotNet.ApplicationBlocks.Data.DAABSectionHandler, GotDotNet.ApplicationBlocks.Data">
</section>
</configSections>

<daabProviders>
<daabProvider alias="misapp" assembly="GotDotNet.ApplicationBlocks.Data" type="GotDotNet.ApplicationBlocks.Data.SqlServer" />
</daabProviders>

在代码中只要这样写 AdoHelper helper = AdoHelper.CreateHelper("misapp");

但是这里我有两个问题:

一、在天行者的文章里没有介绍我们怎么实例化一个IDbConnection,这在启用外部事务的时候是必须的。这点看起来比较好解决,我们可以写一个CreateConnection的工厂方法。

二、天行者的文章里也没有提到如何实例化IDataParameter,因为他是通过ADOHelper.GetSpParameterSet来得到IDataParameter的个数和类型。但如果ADOHelper.GetSpParameterSet不能使用怎么办?这种情况确实存在,比如说在Sybase 9.1.2下就行不通,具体请参见我的另一篇文章 使用DAAB 3.1连接Sybase ASE 11.9.2数据库的两个问题(原创)在这种情况下我们只能自己实例化IDataParameter。修改于2006/07/07,由于使用OracleClient连接Oracle,其中同Odbc连接有很大的差异,比方说返回结果集只能用ref cursor,而且对于存储过程来说ExecuteScalar不能使用,因此,我们AdoHelper.ExecuteScalar方法不是通用的,因此下面的代码已经取消了对Oracle的支持)

下面是我自己写的实现上述两个问题的代码,代码未经过详细测试,本人不承担使用该代码的任何后果。

None.gif public   enum  DatabaseType: byte
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    Sybase 
= 1,
InBlock.gif    MSSqlServer2000 
= 2,
InBlock.gif    //Oracle 
= 3,
InBlock.gif    MSServerODBC
=4
InBlock.gif
ExpandedBlockEnd.gif}

None.gif
None.gif
public   class  DataAccessConfigMgr
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
public static string GetXTERPCURBSConnStr()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
InBlock.gif        
return ConfigurationSettings.AppSettings["SQLconnstr"];
ExpandedSubBlockEnd.gif    }

InBlock.gif    
public static DatabaseType GetXTERPCURBSDBType()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif
InBlock.gif        
string dbType= ConfigurationSettings.AppSettings["DatabaseType"];
InBlock.gif        
if(dbType.ToUpper().IndexOf("SYBASE")!=-1)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return DatabaseType.Sybase;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
else if (dbType.ToUpper().IndexOf("MSSQLSERVER2000")!=-1)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return DatabaseType.MSSqlServer2000;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
else if (dbType.ToUpper().IndexOf("ORACLE")!=-1)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
return DatabaseType.Oracle;
ExpandedSubBlockEnd.gif        }

InBlock.gif        
else if (dbType.ToUpper().IndexOf("MSSERVERODBC")!=-1)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif    
return DatabaseType.MSServerODBC;
ExpandedSubBlockEnd.gif        }

InBlock.gif    
InBlock.gif    
throw new Exception("don't know this database type");
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
public   enum  XTERPType
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
ExpandedSubBlockStart.gifContractedSubBlock.gif    
/**//* 
InBlock.gif    这里定义XTERPType枚举,使用者只需要将XTERPType枚举作为
InBlock.gif    参数传递给CreateDataParameter方法,减少了出错的可能。
InBlock.gif    如果出现枚举不一致的情况,如C#的Decimal在Odbc中需要映射为
InBlock.gif    OdbcType.Double而不是OdbcType.Decimal,而在SqlServer中可以
InBlock.gif    使用SqlDbType.Decimal。因此我们使用XTERPType.Decimal根据
InBlock.gif    不同的数据库映射为不同的枚举,在DBFactory.CreateDataParameter
InBlock.gif    方法中会有体现。这里我们只给出几种常用的数据类型,并且对于在
        Oracle下并没有具体的测试,如果有不一致的情况,请参照Odbc中对
        OdbcType.Double的处理方法。
ExpandedSubBlockEnd.gif    
*/

InBlock.gif    Char 
= 1,
InBlock.gif    DateTime 
= 2,
InBlock.gif    Decimal 
= 3,
InBlock.gif    Int 
= 4,
InBlock.gif    VarChar 
= 5
ExpandedBlockEnd.gif}

None.gif
None.gif
public   class  DBFactory
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    
private static DatabaseType dbType=DataAccessConfigMgr.GetXTERPCURBSDBType();
InBlock.gif    
private DBFactory()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
ExpandedSubBlockEnd.gif    }

InBlock.gif    
public static IDbConnection CreateConnection(string connstr)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
switch (dbType)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
case DatabaseType.Sybase:
InBlock.gif                
return new OdbcConnection(connstr);
InBlock.gif                
InBlock.gif            
case DatabaseType.MSSqlServer2000:
InBlock.gif                
return new SqlConnection(connstr);
InBlock.gif                
InBlock.gif            //
case DatabaseType.Oracle:
InBlock.gif             //   
return new OracleConnection(connstr);
InBlock.gif                
InBlock.gif            
case DatabaseType.MSServerODBC:
InBlock.gif                
return new OdbcConnection(connstr);
InBlock.gif                
ExpandedSubBlockEnd.gif        }

InBlock.gif        
throw new Exception("don't know this database type");
InBlock.gif        
ExpandedSubBlockEnd.gif    }

InBlock.gif    
public static IDbConnection CreateConnection()
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif   
return CreateConnection(DataAccessConfigMgr.GetXTERPCURBSConnStr());
ExpandedSubBlockEnd.gif    }

InBlock.gif    
public static IDataParameter CreateDataParameter(string parameterName,XTERPType type)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif    IDataParameter param;
InBlock.gif        Type xtType
=typeof(XTERPType);
InBlock.gif        Type sysType;
InBlock.gif        Enum dbtype;
InBlock.gif        
switch(dbType)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
InBlock.gif            
case DatabaseType.Sybase:
InBlock.gif                sysType
=typeof(OdbcType);
ExpandedSubBlockStart.gifContractedSubBlock.gif                
/**//*
InBlock.gif                                Enum.GetName(xtType,type)得到传递的XTERPType枚举的字符串,然后
InBlock.gif                通过Enum.Parse(sysType,Enum.GetName(xtType,type))将一个枚举常数
InBlock.gif                的名称表示转换成等效的枚举对象,由于得到的是Object,我们还需要
InBlock.gif                强制转换为相应的枚举类型。在这里,我们会对不一致的情况进行判断修改
InBlock.gif                如:Odbc中采用OdbcType.Double而不是OdbcType.Decimal,我们通过判断
InBlock.gif                传递的XTERPType枚举是否为XTERType.Decimal来决定是否修改为合适的枚举
InBlock.gif
InBlock.gif
ExpandedSubBlockEnd.gif                
*/

InBlock.gif                dbtype
=(OdbcType)Enum.Parse(sysType,Enum.GetName(xtType,type));
InBlock.gif                param
=new OdbcParameter();
InBlock.gif                param.ParameterName
=parameterName;
InBlock.gif                
if(type.Equals(XTERPType.Decimal))
InBlock.gif                    ((OdbcParameter)param).OdbcType
=OdbcType.Double;
InBlock.gif                
else
InBlock.gif                    ((OdbcParameter)param).OdbcType
=(OdbcType)dbtype;
InBlock.gif                
return param;
InBlock.gif            
case DatabaseType.MSSqlServer2000:
InBlock.gif                sysType
=typeof(SqlDbType);
InBlock.gif                dbtype
=(SqlDbType)Enum.Parse(sysType,Enum.GetName(xtType,type));
InBlock.gif                
string s=Enum.Format(sysType, Enum.Parse(sysType,Enum.GetName(xtType,type)), "d");
InBlock.gif                param
=new SqlParameter();
InBlock.gif                param.ParameterName
=parameterName;
InBlock.gif                ((SqlParameter)param).SqlDbType
=(SqlDbType)dbtype;
InBlock.gif                
return param;
InBlock.gif            
case DatabaseType.MSServerODBC:
InBlock.gif                sysType
=typeof(OdbcType);
InBlock.gif                dbtype
=(OdbcType)Enum.Parse(sysType,Enum.GetName(xtType,type));
InBlock.gif                param
=new OdbcParameter();
InBlock.gif                param.ParameterName
=parameterName;
InBlock.gif                
if(type.Equals(XTERPType.Decimal))
InBlock.gif                    ((OdbcParameter)param).OdbcType
=OdbcType.Double;
InBlock.gif                
else
InBlock.gif                    ((OdbcParameter)param).OdbcType
=(OdbcType)dbtype;
InBlock.gif                
return param;
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif        
InBlock.gif        
throw new Exception("Can't create correct parameter");
InBlock.gif
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

 在web.config配置如下

None.gif   < configSections >   
None.gif  
< section  name ="daabProviders"  type ="GotDotNet.ApplicationBlocks.Data.DAABSectionHandler, GotDotNet.ApplicationBlocks.Data" >   
None.gif  
</ section >   
None.gif 
</ configSections >   
None.gif 
None.gif 
< daabProviders >   
None.gif  
<!-- <daabProvider alias="misapp" assembly="GotDotNet.ApplicationBlocks.Data" type="GotDotNet.ApplicationBlocks.Data.SqlServer" />   -->
None.gif  
< daabProvider  alias ="misapp"  assembly ="GotDotNet.ApplicationBlocks.Data"  type ="GotDotNet.ApplicationBlocks.Data.Odbc"   />   
None.gif 
</ daabProviders >   
None.gif  
< appSettings >
None.gif      
<!--
None.gif         设置DatabaseType,系统判断是否包含Sybase,MSSqlServer2000,MSServerOdbc,Oracle创建相应的IDbConnection和IDataParameter
None.gif         Oracle未测试
None.gif      
-->
None.gif      
< add  key ="DatabaseType"  value ="Sybase 9.1.2"   />
None.gif      
<!-- <add key="DatabaseType" value="MSSqlServer2000" /> -->
None.gif      
<!-- <add key="DatabaseType" value="MSServerOdbc" /> -->
None.gif      
None.gif      
<!--
None.gif         设置相应的字符串
None.gif      
-->
None.gif      
None.gif      
<!--  Sybase ODBC -->
None.gif      
< add  key ="SQLconnstr"  value ="Driver={SYBASE SYSTEM 11};Srvr=basil;Database=XTERPCURBS;Uid=sa;pwd="   />
None.gif      
None.gif      
<!--  SqlServer ODBC -->
None.gif      
<!-- <add key="SQLconnstr" value="Driver={SQL Server};Server=basil;Database=XTERPCURBS;Trusted_Connection=yes;Uid=sa;pwd=" />  -->
None.gif      
None.gif      
<!--  SqlServer SqlClient -->
None.gif      
<!-- <add key="SQLconnstr" value="server=localhost;database=XTERPCURBS;uid=sa;pwd=;" />  -->
None.gif     
None.gif     
None.gif      
<!-- <add key="SQLconnstr" value="Provider=SQLOLEDB;Data Source=basil;Initial Catalog=test;Integrated Security=SSPI" /> -->
None.gif  
</ appSettings >


在代码中这样使用:
None.gif private  GDN.AdoHelper helper = GDN.AdoHelper.CreateHelper( " misapp " );
None.gif
using ( IDbConnection conn = DBFactory.CreateConnection(DataAccessConfigMgr.GetXTERPCURBSConnStr()))
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    conn.Open();
InBlock.gif    IDbTransaction transaction
=conn.BeginTransaction();
InBlock.gif
InBlock.gif
InBlock.gif    
try
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        IDataParameter [] searchParms 
= new IDataParameter[1];
InBlock.gif        searchParms[
0= DBFactory.CreateDataParameter("@bh",XTERPType.VarChar);
InBlock.gif        searchParms[
0].Value = bh;
InBlock.gif        helper.ExecuteNonQuery(transaction,
"delYsqlBxMx",searchParms);
InBlock.gif
InBlock.gif        
foreach(DataRow dr in BXCredDS.Tables[BaoXiaoPingZhengData.BAOXIAOMINGXI_TABLE].Rows)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            searchParms 
= new IDataParameter[4];
InBlock.gif            searchParms[
0]=DBFactory.CreateDataParameter("@bh",XTERPType.VarChar);
InBlock.gif            searchParms[
1]=DBFactory.CreateDataParameter("@xh",XTERPType.Int);
InBlock.gif            searchParms[
2]=DBFactory.CreateDataParameter("@code",XTERPType.VarChar);
InBlock.gif            searchParms[
3]=DBFactory.CreateDataParameter("@je",XTERPType.Decimal);
InBlock.gif        
InBlock.gif            searchParms[
0].Value=bh;
InBlock.gif            searchParms[
1].Value=Convert.ToInt32(dr[BaoXiaoPingZhengData.XUHAO_FIELD]);
InBlock.gif            searchParms[
2].Value=dr[BaoXiaoPingZhengData.CODE_FIELD].ToString();
InBlock.gif            searchParms[
3].Value=Convert.ToDecimal(dr[BaoXiaoPingZhengData.SUM_FIELD]);
InBlock.gif            
InBlock.gif            helper.ExecuteNonQuery(transaction,
"insertYsqlBxMx",searchParms);
InBlock.gif        
InBlock.gif
ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif        transaction.Commit();
InBlock.gif        conn.Close();
InBlock.gif    
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif    
catch(Exception ex)
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        transaction.Rollback();
InBlock.gif        conn.Close();
InBlock.gif        
throw ex;
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值