Oracle .NET DATA Provider的问题 - 寻找其他选项

时间:2016-03-02 06:32:34

标签: .net oracle oracle11g odp.net oracle9i

在开始之前,我建议你深呼吸并理解,这是一个很长的问题,在单一背景下有3-4个问题。所以在阅读时要有耐心。 (如果你需要任何东西,代码样本或其他任何我正在认真寻找解决方案,请写评论。)

最近我一直在与客户合作,他希望在 Oracle 中拥有应用程序数据库。该应用程序基于 ASP.NET MVC 构建。

我们选择 Oracle 11g 表示开发环境,客户已确认相同。我们决定选择支持ORM(EF)的ODAC 32bit .NET Provider。我们首先进行了一个实施CRUD操作的试验案例,一切正常。然后我们开始开发实际的客户需求。在2-3个月内,该产品已准备好交付。到目前为止,一切都在ASP.NET和Oracle 11g上运行良好。当我们进行部署和UAT时,我们发现客户端正在为他现有的ERP配备oracle 9i,这与我们开发的版本不匹配。因此,我们在互联网上搜索验证相同的ODAC提供商是否与Oracle 9i兼容。我们发现提到的引用它与Oracle 9i兼容。

我们刚刚将数据库迁移到Oracle 9i服务器,相应地更改了EF模型并发现了以下问题:

1。交易未自动提交!

using (TransactionScope transaction = new TransactionScope())
{
    // some code written here
}

相同的代码正在使用11g,当移动到Oracle 9i时,它停止工作.Transactions在完成using语句后没有自动提交。我们故意在使用块中写了transaction.commit();并开始工作。

这是预期的行为吗?

2。 VARCHAR2数据类型和ODP NET提供程序的问题。 我们在数据库中创建了一些存储过程,其中Varchar2和其他数据库类型作为参数。在使用ADO.NET样式(OracleConnection,OracleCommand和OracleParameter)访问这些存储过程时,我们所知道的是,即使数据通过,具有VARCHAR2数据类型的参数有时会截断数据to parameter的大小小于给定的table列的大小。它只是从末尾随机删除了多少个字符。 Problem is also logged here in oracle forum

我们无法找到解决方法。

第3。内联查询大小限制(不包含字符)。 为了解决#2中提到的问题,我们意识到我们应该将这些存储过程转换为内联查询并使用ADO.NET(在校日编码时使用旧样式)调用它们!我们将所有存储过程转换为行脚本,并按以下方式编写

OracleCommand command=new OracleCommand("Select * from something",Connection);

对其他DML语句使用相同的技术。现在一切正常,我们进行了UAT,我们让应用程序正常运行。 10-15天后,我们发现了奇怪的问题。如果查询(内联查询)的大小超过4000个字符,则Oracle服务器抛出异常,指出“查询执行时间过长”(我不记得异常或消息,但它与我所写的类似) 。我们在开发环境中获取了样本数据并通过代码进行调试,结果发现SQL查询的大小太长,超过32000到64000个字符! 我们知道对此的解决方案是相同的'如果我们能以某种方式能够正确地调用存储过程!'但我们不能,因为我们没有任何选择。

作为一种解决方案,我们在数据库中重新创建了这些存储过程,并将这些存储过程称为内联!

OracleCommand command=new OracleCommand("BEGIN ProceduretoCall(Param1,Param2); END;",Connection);

从那时起它就一直在运作。

考虑到上述问题,

  1. 我无法以通常的方式从ASP.NET调用存储过程(CommandType.StoredProcedure)上面的#problem-1
  2. 插入或更新后,我无法返回任何数据或标量值或从存储过程返回值。上面的#problem-3
  3. 我无法在代码级别使用事务。 (它一直说,分布式事务已初始化,但实际上我根本没有分布式事务!)
  4. 为什么Go Live之后的所有上述内容? 我几乎一直在解决这个问题几乎是噩梦,我已经解决了一个月,这让我想到了

    ODP.NET / ODAC工具真的可靠吗?

    如果没有,那么根据您的经验,我可以选择哪些其他选项? (请注意,ODBC也与Oracle 9i有类似的问题。)

    下周我更有可能在类似的项目上工作,我想这次我想做好更好的方法。

1 个答案:

答案 0 :(得分:0)

我强烈建议将每个要点隔离为一个单独的问题。每一个都是具体的,并且有它自己的问题,这将是一个混乱,保持一切。

其次,我同意这个评论。甚至2003年发布的Oracle 10gR1也不受支持。也许你需要接受一些责任,不要事先提出这个问题,但我也不认为你说他们正在使用支持的oracle版本是不合理的。

那说我会快速刺伤:

  1. TransactionScope永远不会自动提交。您需要添加transaction.Complete()。 WAS承诺之前唯一出乎意料的行为。

  2. 引用的文章提到在重新编译oracle进程时解决了该问题,并指出了解决该问题的oracle补丁集。如果是这种情况,我不认为这是一个odp.net问题。如果您需要,可以粘贴proc签名以及如何添加参数以查看是否有一些tweek可以尝试。但同样,我会将其作为一个单独的问题发布。

  3. 3.2 - 我不知道你是如何返回标量的 - 你需要在参数上使用refcursor,我不确定如何创建一个匿名块会改变它。我想你需要发布更多的代码,特别是你发送参数的方式。

    3.3 - 当事务包含多个连接时,TransactionScope会自动从本地事务转换为分布式连接,即使它们属于同一个数据库。但是,我不认为这个功能在11g之前得到支持,以前所有的事务都是以分布式开始的。但是,我不确定9i是否有这个概念可能解释了你所看到的奇怪的自动提交。

    在过去的7年里,ODP.net对我来说完全可靠。也就是说,我总是在支持的oracle版本上运行它,并为该版本设置了合理的最新补丁。