使用ODP.NET与企业库DAAB连接Oracle

我们的应用程序使用Enterprise Library DAAB来支持oracle和sql数据库。

其中一个存储过程用于将图像上载到表格。 它是一个BLOB字段,参数设置为DbType.Binary。

这个function对SQL没有任何问题,但是当遇到Oracle时,我遇到了32K参数大小限制问题。

正如SO中所建议的那样,我将代码移到了ODP.NET,但我仍面临同样的问题。

我的App.config文件设置:

  

在我的应用程序代码中,我使用企业库来访问数据库

  Database db = DatabaseFactory.CreateDatabase(); DbCommand cmd = db.GetStoredProcCommand(spName); cmd.CommandType = CommandType.StoredProcedure; db.AddInParameter(cmd, "DOCIMAGE", DbType.Binary, GetByteArrayFromFile(filePath)); db.AddOutParameter(cmd, "return_value", DbType.Int32, 128); int row = db.ExecuteNonQuery(cmd); 

我的项目中引用了以下程序集:

在此处输入图像描述

现在,当我运行应用程序时,Ent Lib DAAP应该使用Oracle.DataAccess.Client,但它仍然通过System.Data.OracleClient连接到oracle db。 所以还有32K的限制。

在此处输入图像描述

为什么它没有使用Oracle数据提供程序,因为我已在App.config中明确提到过?

在一篇文章中,提到使用以下代码段作为解决方法,

 DbProviderFactory providerFactory = DbProviderFactories.GetFactory("Oracle.DataAccess.Client"); Database db = GenericDatabase(connectionString, providerFactory); 

这个看起来很有效。

在此处输入图像描述

但实例化的数据库是GenericDatabase而不是OracleDatabase,这可能就是为什么即使这个工作仍然在文件大小超过32K时抛出exception。

如何将ODP.NET与Enterprise Library一起用于32K大小限制问题?

决议

我跟着hridya走了过来。 正如他所提到的那样,XML注释错误可以被关闭(看这里) 。 还有一些命名空间冲突通过选择Oracle.DataAccess.Client来解决。 在这之后,它成功编译。

这是我用来测试更改的示例应用程序的代码片段。 (示例解决方案现在引用新编译的数据和公共dll。)

 Database db = DatabaseFactory.CreateDatabase(); DbCommand cmd = db.GetStoredProcCommand(sqlCode); cmd.CommandType = CommandType.StoredProcedure; db.AddInParameter(cmd, "DOCIMAGE", DbType.Binary, GetByteArrayFromFile(filePath)); db.AddOutParameter(cmd, "return_value", DbType.Int32, 128); int rowID = db.ExecuteNonQuery(cmd); 

我检查了命令对象,现在它的类型是Oracle.DataAccess.Client.OracleCommand,而之前它是System.Data.OracleClient.OracleCommand。

请记住,因为我已经修改了DAAB以使用ODP.NET,所以我不需要使用providerMappings标记在配置文件中显式设置提供程序。

但是当文件大小超过32K时,我仍然会得到相同的错误。逐行进入代码显示问题出在DbType.Binary上。 它没有改为正确的OracleDbType。

为了使其工作,我在Enterprise Lib的数据项目中添加了一个代码修复。

文件: \ Oracle \ OracleDatabase.cs

方法: AddParameter

原始代码:

 public override void AddParameter(DbCommand command, string name, DbType dbType, int size, ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value) { if (DbType.Guid.Equals(dbType)) { object convertedValue = ConvertGuidToByteArray(value); AddParameter((OracleCommand)command, name, OracleDbType.Raw, 16, direction, nullable, precision, scale, sourceColumn, sourceVersion, convertedValue); RegisterParameterType(command, name, dbType); } else { base.AddParameter(command, name, dbType, size, direction, nullable, precision, scale, sourceColumn, sourceVersion, value); } } 

添加了DbType.Binary的条件

修改代码:

 public override void AddParameter(DbCommand command, string name, DbType dbType, int size, ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value) { if (DbType.Guid.Equals(dbType)) { object convertedValue = ConvertGuidToByteArray(value); AddParameter((OracleCommand)command, name, OracleDbType.Raw, 16, direction, nullable, precision, scale, sourceColumn, sourceVersion, convertedValue); RegisterParameterType(command, name, dbType); } else if(DbType.Binary.Equals(dbType)) { AddParameter((OracleCommand)command, name, OracleDbType.Blob, size, direction, nullable, precision, scale, sourceColumn, sourceVersion, value); } else { base.AddParameter(command, name, dbType, size, direction, nullable, precision, scale, sourceColumn, sourceVersion, value); } } 

我不知道如果这样做的正确方法或其他一些光滑的解决方法已经可用。 但它奏效了。

我希望以下步骤能为您提供正确的结果。

用Oracle.DataAccess.Client替换System.Data.OracleClient; 和Oracle.DataAccess.Types

下载并安装最新版本的Microsoft Enterprise Library ver 3.1可在此处找到: – http://msdn2.microsoft.com/en-us/library/aa480453.aspx

从Oracle网站下载并安装Oracle ODP.Net您的DLL文件应该是: – C:\ oracle \ product \ 11.1.0 \ client_1 \ odp.net \ bin \ 2.x \ Oracle.DataAccess.dll

当它提示您安装源时,请使用复选框。

如果没有,则在以下路径C:\ Program Files \ Microsoft Enterprise Library 3.1 – 2007年5月\ src上运行msi

库的代码存储在以下路径C:\ EntLib3Src \ App Blocks中

备份原始的src文件夹,以备日后需要时使用 – C:\ EntLib3Src \ App Blocks \ Src

打开解决方案文件EnterpriseLibrary.sln并转到Data Access Application Block下的数据项目

将Oracle.DataAccess.dll引用添加到数据项目。 您的DLL文件应该是: – C:\ oracle \ product \ 11.1.0 \ client_1 \ odp.net \ bin \ 2.x \ Oracle.DataAccess.dll

搜索并替换以下[您可以下载并使用本文附带的更新的DLL]

文件: – C:\ EntLib3Src \ App Blocks \ Src \ Data \ Oracle \ OracleDatabase.cs
文件: – C:\ EntLib3Src \ App Blocks \ Src \ Data \ DatabaseConfigurationView.cs
文件: – C:\ EntLib3Src \ App Blocks \ Src \ Data \ Oracle \ OracleDataReaderWrapper.cs

查找: – using System.Data.OracleClient;
替换为: – using Oracle.DataAccess.Client; using Oracle.DataAccess.Types; using Oracle.DataAccess.Client; using Oracle.DataAccess.Types;

文件: – C:\ EntLib3Src \ App Blocks \ Src \ Data \ Configuration \ DbProviderMapping.cs类: – DbProviderMapping

查找: – System.Data.OracleClient
替换为: – Oracle.DataAccess.Client

文件: – C:\ EntLib3Src \ App Blocks \ Src \ Data \ Configuration \ Manageability \ ConnectionStringsManageabilityProvider.cs
方法: – AddAdministrativeTemplateDirectives
查找: – System.Data.OracleClient
替换为: – Oracle.DataAccess.Client

文件: – C:\ EntLib3Src \ App Blocks \ Src \ Data \ Oracle \ OracleDatabase.cs
方法: – AddParameter

查找: – public void AddParameter(OracleCommand command, string name, OracleType oracleType, int size, ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value)

替换为: – public void AddParameter(OracleCommand command, string name, OracleDbType oracleType, int size, ParameterDirection direction, bool nullable, byte precision, byte scale, string sourceColumn, DataRowVersion sourceVersion, object value)

原因: – OracleType替换为OracleDbType作为odp.net API中类型名称的第三个参数

文件: – C:\ EntLib3Src \ App Blocks \ Src \ Data \ Oracle \ OracleDatabase.cs
删除: – [OraclePermission(SecurityAction.Demand)]

如果有人请反馈会议,请不要知道该怎么做

文件: – C:\ EntLib3Src \ App Blocks \ Src \ Data \ Oracle \ OracleDatabase.cs
找到: – OracleType.Raw
替换为: – OracleDbType.Raw

查找: – param.OracleType
替换为: – param.OracleDbType

查找: – OracleType.Cursor
替换为: – OracleDbType.RefCursor

查找: – parameter.OracleType
替换为: – parameter.OracleDbType

现在编译,如果你得到一个错误,请执行以下警告作为错误:XML注释 – 删除突出显示的错误内容/用approp注释替换它希望它现在应该编译好。

现在,通过编译上述项目生成的DLL可以用于SqlServer和Oracle [ODP.Net]

有点迟到了,但我看不出有什么理由说明为什么响应者建议使用EL3.1这是非常过时的 – 5是最新版本(并且在这篇文章之前已经推出了差不多2年)和OP根据代码示例使用4.1。 将ODP与EL5一起使用要简单得多(我自己也使用了EntlibContrib项目),虽然因为我们不使用BLOB而无法说出参数大小的任何潜在问题,但EntlibContrib本身允许使用OracleDbType,所以我认为这可能不是问题。

以防万一有人在这篇文章中发现想知道如何让EL5和ODP玩得很好而且最小化,我可以提供详细信息 – PM me。