使用Enterprise Library操作Oracle的疑点难点总结

本文介绍了使用EnterpriseLibrary数据访问模块处理Oracle存储过程中的游标返回数据的方法,对比了传统ADO.NET方式,展示了如何简化代码并提高开发效率。
我们知道,Microsoft patterns & practices小组开发的Enterprise Library是一款非常好的组件,其有很多个模块,包括数据访问、配置、加密、IOC容器、日志、异常处理等内容,其中数据访问模块是其中非常不错的一个数据访问组件,提供了对各种数据库操作的抽象封装,使用数据访问起来基本上是对各种数据库是透明的,最重要的是,简化了代码,提高了开发效率。
本文介绍Enterprise Library中的数据访问模块在操作Oracle过程中的一些经验总结,作为自己和博友做数据库访问的一个参考。
1、存储过程的游标处理
这个和SqlServer数据获取有点不同,在Oracle中用存储过程返回数据内容,必须定义一个游标,如下面所示的Oracle存储过程
ContractedBlock.gif ExpandedBlockStart.gif Code
------------------------------------
--
Author:伍华聪
--
Create time:2009-08-21 
--
Description:创建一个包,含有一个游标类型:(一个数据库中只需作一次)  
--
----------------------------------
 CREATE OR REPLACE PACKAGE MyCURSOR 
 
AS 
     TYPE cur_OUT 
IS REF CURSOR
 
End
 
/ 

------------------------------------
--
Author:伍华聪
--
Create time:2009-08-21 
--
Description:检索表中所有的数据 
--
----------------------------------
 Create Or Replace Procedure WUHUACONG.PUB_PHONE_SelectAll 
 ( cur_OUT OUT MyCURSOR.cur_OUT ) 
 
AS 
 
Begin 
 
OPEN cur_OUT FOR Select * from GIS.PUB_PHONE; 
 
End
 
/ 

------------------------------------
--
Author:伍华聪
--
Create time:2009-08-21 
--
Description:以字段COMPANYID为关键字,检索表中的数据 
--
----------------------------------
 Create Or Replace Procedure WUHUACONG.PUB_PHONE_SelectByCOMPANYID 
 ( 
     cur_OUT OUT MyCURSOR.cur_OUT  ,
     p_COMPANYID 
IN GIS.PUB_PHONE.COMPANYID%TYPE 
 ) 
 
AS 
 
Begin 
 
OPEN cur_OUT FOR Select * from GIS.PUB_PHONE Where COMPANYID = p_COMPANYID ; 
 
End
 
/ 

大家看到,上面的SelectAll和SelectBy存储过程都需要一个游标的参数,是OUT类型的,也就是你获取数据需要定义一个输出的游标参数,我们看看普通的数据访问是如何做的。
ContractedBlock.gif ExpandedBlockStart.gif Code
            List<LeagueCompany> list = new List<LeagueCompany>();
            
try
            {
                
using (OracleConnection con = new OracleConnection("Data Source=DEVBAK;user=WUHUACONG;password=WUHUACONG;"))
                {
                    OracleCommand cmd 
= new OracleCommand();
                    cmd.Connection 
= con;
                    cmd.Parameters.Add(
"cur_OUT", OracleType.Cursor).Direction = ParameterDirection.Output;
                    cmd.CommandType 
= CommandType.StoredProcedure;
                    cmd.CommandText 
= "PUBDB.sp_LeagueCompanyInit";
                    cmd.Connection.Open();
                    OracleDataReader reader 
= cmd.ExecuteReader();
                    
if (reader.HasRows)
                    {
                        
while (reader.Read())
                        {
                            
#region 解析字段内容
                            LeagueCompany c 
= new LeagueCompany();
                            
if (reader["companyid"!= DBNull.Value)
                            {
                                c.CompanyId 
= int.Parse(reader["companyid"].ToString());
                            }
                            
if (reader["companyname"!= DBNull.Value)
                            {
                                c.CompanyName 
= reader["companyname"].ToString();
                            }
                            
if (reader["mainid"!= DBNull.Value)
                            {
                                c.MainId 
= int.Parse(reader["mainid"].ToString());
                            }
                            
if (reader["subid"!= DBNull.Value)
                            {
                                c.SubId 
= int.Parse(reader["subid"].ToString());
                            }
                            
if (reader["teamid"!= DBNull.Value)
                            {
                                c.TeamId 
= int.Parse(reader["teamid"].ToString());
                            }
                            
if (reader["levelid"!= DBNull.Value)
                            {
                                c.Level 
= int.Parse(reader["levelid"].ToString());
                            } 
                            
#endregion
                            list.Add(c);
                        }
                    }
                }
            }
            
catch (Exception ex)
            {
                LogHelper.Error(ex);
                MessageBox.Show(
string.Format("获取公司列表异常->" + ex.Message));
            }

            
this.dataGridView1.DataSource = list;
        }

上面是不用Enterprise Library数据访问而直接使用ADO.NET的数据对象访问的数据库,可以看到存在两个问题,一个是数据操作的代码比较臃肿,如果你使用很多这种操作,就会发现很多重复性的代码,另外就是数据解析的部分也比较臃肿重复,我们下面看看使用了Enterprise Library数据访问模块后的效果是如何。
ContractedBlock.gif ExpandedBlockStart.gif Code
            //Database db = DatabaseFactory.CreateDatabase();//通过Web.Config或者*.exe.Config配置文件读取
            Database db = new OracleDatabase("Data Source=DEVBAK;user=WUHUACONG;password=WUHUACONG;");//直接传递连接字符串,适合自定义配置文件的处理
            string sqlCommand = "PUBDB.sp_LeagueCompanyInit";
            DbCommand dbCommand 
= db.GetStoredProcCommand(sqlCommand);

        
//由于EnterpriseLibrary 默认的数据访问游标是cur_OUT,所以下面可以省略
            
//OracleParameter cursorParam = new OracleParameter("cur_OUT", OracleType.Cursor);
            
//cursorParam.Direction = ParameterDirection.Output;
            
//dbCommand.Parameters.Add(cursorParam);

            List
<LeagueCompany> list = new List<LeagueCompany>();
            
try
            {
                
using (IDataReader dr = db.ExecuteReader(dbCommand))
                {
                    
while (dr.Read())
                    {
                        
#region 解析字段内容
                        SmartDataReader reader 
= new SmartDataReader(dr);
                        LeagueCompany c 
= new LeagueCompany();
                        c.CompanyId 
= reader.GetInt("companyid");
                        c.CompanyName 
= reader.GetString("companyname");
                        c.MainId 
= reader.GetInt("mainid");
                        c.SubId 
= reader.GetInt("subid");
                        c.TeamId 
= reader.GetInt("teamid");
                        c.Level 
= reader.GetInt("levelid");
                        
#endregion
                        list.Add(c);
                    }
                }
            }
            
catch (Exception ex)
            {
                LogHelper.Error(ex);
                MessageBox.Show(
string.Format("获取公司列表异常->" + ex.Message));
            }

            
this.dataGridView1.DataSource = list;

是不是代码很简短了,这里注意两个地方,一个是我们创建游标的时候,采用cur_OUT来做为它的名称,这样我们就不用增加整个游标的定义了,因为EnterpriseLibrary模块默认给我们增加了这个游标处理(有可以少3行代码了)。另外引入了SmartDataReader对象来处理数据的转换问题,这个类后面附上,以供参考。
由于EnterpriseLibrary 默认的数据访问游标是cur_OUT,如果存储过程的游标名称和cur_OUT不一样,如p_Cur,那么数据库操作代码会变化为下面,这个必须注意。否则你的数据访问总是获取不到而发生错误。

ContractedBlock.gif ExpandedBlockStart.gif Code
            Database db = new OracleDatabase("Data Source=DEVBAK;user=WUHUACONG;password=WUHUACONG;");//直接传递连接字符串,适合自定义配置文件的处理
            string sqlCommand = "PUBDB.sp_LeagueCompanyInit";
            DbCommand dbCommand 
= db.GetStoredProcCommand(sqlCommand);

           OracleParameter cursorParam 
= new OracleParameter("p_Cur", OracleType.Cursor);
           cursorParam.Direction 
= ParameterDirection.Output;
           dbCommand.Parameters.Add(cursorParam);
           
            List
<LeagueCompany> list = new List<LeagueCompany>();
            
try
            {
                
using (IDataReader dr = db.ExecuteReader(dbCommand))
                {
                    
while (dr.Read())
                    {
                        
                    }
                }
            }
            
catch (Exception ex)
            {
                LogHelper.Error(ex);
                MessageBox.Show(
string.Format("获取公司列表异常->" + ex.Message));
            }

下面附上数据解析类的代码,供参考。
http://files.cnblogs.com/wuhuacong/SmartDataReader.rar 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值