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

我们知道,Microsoft patterns & practices小组开发的Enterprise Library是一款非常好的组件,其有很多个模块,包括数据访问、配置、加密、IOC容器、日志、异常处理等内容,其中数据访问模块是其中非常不错的一个数据访问组件,提供了对各种数据库操作的抽象封装,使用数据访问起来基本上是对各种数据库是透明的,最重要的是,简化了代码,提高了开发效率。
本文介绍Enterprise Library中的数据访问模块在操作Oracle过程中的一些经验总结,作为自己和博友做数据库访问的一个参考。
1、存储过程的游标处理
这个和SqlServer数据获取有点不同,在Oracle中用存储过程返回数据内容,必须定义一个游标,如下面所示的Oracle存储过程

------------------------------------
--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类型的,也就是你获取数据需要定义一个输出的游标参数,我们看看普通的数据访问是如何做的。

            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数据访问模块后的效果是如何。

            //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,那么数据库操作代码会变化为下面,这个必须注意。否则你的数据访问总是获取不到而发生错误。

            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 

本文转自博客园伍华聪的博客,原文链接:使用Enterprise Library操作Oracle的疑点难点总结,如需转载请自行联系原博主。

时间: 2024-10-29 17:08:39

使用Enterprise Library操作Oracle的疑点难点总结的相关文章

Enterprise Library 4 数据访问应用程序块

据穿过应用程序层( application layers).以及将修改的数据提交回数据库系统.应用程序块包含对存储过程和内联 SQL 的支持.常规内部(housekeep)处理,如管理连接.创建并缓存参数,都封装在应用程序块的方法中.换句话说,数据访问应用程序块在简单易用的类中提供了对 ADO.NET 的最常用的特性的访问:这提高了开发人员的工作效率. ADO.NET 2.0 提供了如 DbCommand 类和 DbConnection 这样的类,这些类有助于从任何特定数据库实现中抽象出数据提供

在数据库访问项目中使用微软企业库Enterprise Library,实现多种数据库的支持

在我们开发很多项目中,数据访问都是必不可少的,有的需要访问Oracle.SQLServer.Mysql这些常规的数据库,也有可能访问SQLite.Access,或者一些我们可能不常用的PostgreSQL.IBM DB2.或者国产达梦数据库等等,这些数据库的共同特点是关系型数据库,基本上开发的模型都差不多,不过如果我们基于ADO.NET的基础上进行开发的话,那么各种数据库都有自己不同的数据库操作对象,微软企业库Enterprise Library是基于这些不同数据库的操作做的抽象模型,适合多数据

Enterprise Library深入解析与灵活应用(8):WCF与Exception Handling AppBl

Enterprise Library深入解析与灵活应用(8):WCF与Exception Handling AppBlock集成[下] 在上篇中,我详细介绍了如何通过自定义ClientMessageInspector和 ErrorHandler,实现WCF与微软企业库中的Exception Handling Application Block(EHAB)之间的集成.这个方案的基本思路就是:当异常从服务端抛出,利 用EHAB针对某个配置好的异常处理策略进行处理:然后将处理有的异常通过 Servic

Enterprise Library深入解析与灵活应用(8):通过WCF扩展实现与EHAB的集成[

Enterprise Library深入解析与灵活应用(8):通过WCF扩展实现与EHAB的集成[上篇] 在<WCF技术剖析(卷1)>的最后一章,我给出了一个具体的应用WCF的分布式应用实例,我把这个实例命名为PetShop.在这个例子中,我利用WCF的扩展实 现了一些设计.架构模式,比如AOP.IoC等.看过本书的读者,一定还记得我还 通过WCF扩展实现了于微软企业库(Enterprise Library)异常处理应用块 (Exception Handling Application Blo

Enterprise Library深入解析与灵活应用(6):自己动手创建迷你版AOP框架

基于Enterprise Library PIAB的AOP框架已经在公司项目开发中得到广泛的使用,但是最近同事维护一个老的项目,使用到了Enterprise Library 2,所以PIAB是在Enterprise Library 3.0中推出的,所以不同直接使用.为了解决这个问题,我写了一个通过方法劫持(Method Interception)的原理,写了一个简易版的AOP框架.(如果对PIAB不是很了解的读者,可以参阅我的文章MS Enterprise Library Policy Inje

Enterprise Library深入解析与灵活应用(4):创建一个自定义Exception Handl

Enterprise Library深入解析与灵活应用(4):创建一个自定义Exception Handler改变ELAB的异常处理机制 1.背景与动机 微软Enterprise Library ELAB(Exception Handling Application Block)提供了一种基于策略(Policy)的异常 处理方式,在不同的环境中,比如多层架构中不同的层次中,我们可以定义不同的异常处理策略.对于ELAB来说,Exception Handling Policy = Exception

Enterprise Library深入解析与灵活应用(3):倘若将Unity、PIAB、Exception Ha

Enterprise Library深入解析与灵活应用(3):倘若将Unity.PIAB.Exception Handling引入MVP模式 最近在做一个Smart Client Software Factory的项目.熟悉SCSF或者CAB的都应该很清楚MVP这种设计模式.MVP是MVC的一种变体,View和 Mode分别关注于UI的呈现和业务模型,View和Mode完全分离,View通过Presenter实现对业务模型的访问,Presenter"间接"地调 用View实现对UI的操

Enterprise Library深入解析与灵活应用(2):通过SqlDependency实现Cache和Data

Enterprise Library深入解析与灵活应用(2):通过SqlDependency实现Cache和Database的同步 对于一个真正的企业级的应用来说,Caching肯定是一个不得不考虑的因素,合理.有效地利用Caching对于增强应用的Performance(减少 对基于Persistent storage的IO操作).Scalability(将数据进行缓存,减轻了对Database等资源的压力)和Availability(将数据进行缓存 ,可以应对一定时间内的网络问题.Web S

Enterprise Library 3.0体验(2):使用Validation Application Block

一.概述 在Enterprise Library 3.0 December 2006 CTP版中,加入了一个新的成员Validation Application Block,用来实现对业务对象的验证.它支持两种方式的验证,通过特性Attribute和通过配置文件,但是在最新版本中并没有提供配置的设计时支持,我们只能通过手动去修改配置文件来实现,所以本文主要看一下通过Attribute来实现验证. 二.通过ValidationFactory创建验证器 Validation Application