使用ODP.NET将Oracle与企业库DAAB连接起来 [英] Connecting Oracle using ODP.NET with Enterprise Library DAAB

查看:103
本文介绍了使用ODP.NET将Oracle与企业库DAAB连接起来的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我们的应用程序正在使用企业库DAAB支持oracle和sql数据库.

Our application is using Enterprise Library DAAB to support both oracle and sql databases.

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

One of the Stored Procedure is for uploading Image to Table. It's a BLOB field and the parameter is set to DbType.Binary.

此功能对于SQL来说没有任何问题,但是对于Oracle而言 我遇到了32K参数大小限制问题.

This functionality works without any problem for SQL, But when comes to Oracle I hit the 32K parameter size limit issue.

按照SO中的建议,我将代码移到了ODP.NET,但是我仍然面临着同样的问题.

As suggested in SO, I moved the code to ODP.NET, but I am still facing the same problem.

我的App.config文件设置:

My App.config file setting:

<configuration>
<configSections>
    <section name="dataConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Data.Configuration.DatabaseSettings, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" />
</configSections>
<dataConfiguration defaultDatabase="Oracle">
    <providerMappings>
        <add databaseType="Microsoft.Practices.EnterpriseLibrary.Data.Oracle.OracleDatabase, Microsoft.Practices.EnterpriseLibrary.Data, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35"
            name="Oracle.DataAccess.Client" />
    </providerMappings>
</dataConfiguration>
<connectionStrings>
    <add name="Oracle" connectionString="Data Source=MYORACSER;USER ID=UNAME;PASSWORD=MYPWD;"
        providerName="Oracle.DataAccess.Client" />
</connectionStrings>

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

 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的限制.

为什么不使用我在App.config中明确提到的Oracle Data Provider?

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

In one post, It is mentioned to use the following snippet as a workaround,

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

这似乎很有效.

但是实例化的数据库是GenericDatabase而不是OracleDatabase,这也许就是为什么即使文件大小超过32K时,这种解决方法仍会引发异常的原因.

But the instantiated Database is of GenericDatabase instead of OracleDatabase, may be that's why even this work around still throwing exception when file size is over 32K.

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

已解决:

我关注了 hridya . 正如他提到的那样,存在XML注释错误,可以将其关闭(请参阅此处) . 另外,通过选择Oracle.DataAccess.Client也解决了几个命名空间冲突.之后,编译成功.

I followed hridya walk through. As he mentioned there were XML comment errors, which can be turned off (Look here). Also there were couple of namespace conflicts which were resolved by choosing Oracle.DataAccess.Client. After these, It compiled successfully.

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

Here is my code snippet from the sample application I made it to test the changes. (The sample solution now references new compiled Data and Common dlls.)

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.

I checked command object, now it is of type Oracle.DataAccess.Client.OracleCommand whereas previously it was System.Data.OracleClient.OracleCommand.

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

Remember since I have already modified the DAAB to use ODP.NET, I don't need to set the provider explicitly in the config file using providerMappings tag.

但是,当文件大小超过32K时,我仍然遇到相同的错误,逐步进入代码行可以发现问题出在DbType.Binary.它没有更改为正确的OracleDbType.

But I still get the same error when the file size exceeds 32K, Stepping into the code line by line revealed that the problem is with the DbType.Binary. It didn't get changed to proper OracleDbType.

为使其正常工作,我在Enterprise Lib的Data Project中又添加了一个代码修复程序.

To make it work I have added one more code fix in Enterprise Lib's Data Project.

文件: \ 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添加了条件

Added condition for 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);
        }
    }

我不知道这是否是正确的方法或其他一些时髦的解决方法. 但这有效.

I don't know If this the right way to do it or some other sleek workaround is already available. But it worked.

推荐答案

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

I hope the following steps will give you the correct result.

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

To replace System.Data.OracleClient with Oracle.DataAccess.Client; and Oracle.DataAccess.Types

下载并安装最新版本的Microsoft Enterprise Library ver 3.1,可以在这里找到:-

Download and install the latest version of Microsoft Enterprise Library ver 3.1 Can be found here:- 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

Download and install the Oracle ODP.Net from Oracle website Your DLL file should be in :- C:\oracle\product\11.1.0\client_1\odp.net\bin\2.x\Oracle.DataAccess.dll

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

When it prompts you to install the source do so by using the checkbox.

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

If you didn't then run the msi on the following path C:\Program Files\Microsoft Enterprise Library 3.1 - May 2007\src

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

The code for the library gets stored on the following path C:\EntLib3Src\App Blocks

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

Take a backup of the original src folder in case you need them later - C:\EntLib3Src\App Blocks\Src

打开解决方案文件EnterpriseLibrary.sln并进入数据访问应用程序块下的数据项目

Open the solution file EnterpriseLibrary.sln And get to the data project under Data Access Application Block

将Oracle.DataAccess.dll参考添加到数据项目.您的DLL文件应该位于:-C:\ oracle \ product \ 11.1.0 \ client_1 \ odp.net \ bin \ 2.x \ Oracle.DataAccess.dll

Add Oracle.DataAccess.dll Reference to the Data Project. Your DLL file should be in :- C:\oracle\product\11.1.0\client_1\odp.net\bin\2.x\Oracle.DataAccess.dll

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

Search and replace the following [ Instead you could download and use the updated DLL thats attached to this article]

文件:-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

File :- C:\EntLib3Src\App Blocks\Src\Data\Oracle\OracleDatabase.cs
File :- C:\EntLib3Src\App Blocks\Src\Data\DatabaseConfigurationView.cs
File :- C:\EntLib3Src\App Blocks\Src\Data\Oracle\OracleDataReaderWrapper.cs

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

Find :- using System.Data.OracleClient;
Replace with:- using Oracle.DataAccess.Client; using Oracle.DataAccess.Types;

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

File :- C:\EntLib3Src\App Blocks\Src\Data\Configuration\DbProviderMapping.cs Class:- DbProviderMapping

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

Find :- System.Data.OracleClient
Replace with:- Oracle.DataAccess.Client

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

File :- C:\EntLib3Src\App Blocks\Src\Data\Configuration\Manageability\ ConnectionStringsManageabilityProvider.cs
Method:- AddAdministrativeTemplateDirectives
Find :- System.Data.OracleClient
Replace with:- Oracle.DataAccess.Client

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

File :- C:\EntLib3Src\App Blocks\Src\Data\Oracle\OracleDatabase.cs
Method:- 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)

Find :- 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)

Replace with:- 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中的类型名称

Reason:- OracleType replaced with OracleDbType as the third parameter as that the type name in the odp.net API

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

File:- C:\EntLib3Src\App Blocks\Src\Data\Oracle\OracleDatabase.cs
Remove:- [OraclePermission(SecurityAction.Demand)] -

如果有人请反馈会议作简要介绍,该怎么办

Haven't got a clue what that does if someone does please brief on feedback session

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

File:- C:\EntLib3Src\App Blocks\Src\Data\Oracle\OracleDatabase.cs
Find:- OracleType.Raw
Replace with:- OracleDbType.Raw

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

Find:- param.OracleType
Replace with:- param.OracleDbType

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

Find:- OracleType.Cursor
Replace with:- OracleDbType.RefCursor

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

Find:- parameter.OracleType
Replace with:- parameter.OracleDbType

立即编译,如果遇到错误,请执行以下警告作为错误:XML注释-删除突出显示的错误内容/将其替换为适当的注释,希望它现在可以正常编译.

Compile now and if you get an error do the following Warning as Error : XML comment on - Remove the highlighted error content / replace it with approp comment Hopefully it should compile fine now.

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

Now the DLL that was generated by compiling the above project can be used against both SqlServer and Oracle [ODP.Net]

这篇关于使用ODP.NET将Oracle与企业库DAAB连接起来的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆