【发布时间】:2016-06-14 21:13:15
【问题描述】:
在我开始之前,我建议你深呼吸并理解,这是一个很长的问题,在单个上下文中有 3-4 个问题。所以阅读时要有耐心。 (如果您需要任何东西、代码示例或任何我正在认真寻找解决方案的东西,请在评论中写下)。
最近我一直在与一位客户合作,他希望在 Oracle 中拥有应用程序数据库。该应用程序基于 ASP.NET MVC 构建。
我们选择Oracle 11g express作为开发环境,客户已经确认了。我们决定使用支持 ORM (EF) 的 ODAC 32bit .NET Provider。我们首先进行了一个实施 CRUD 操作的试验案例,一切正常。然后我们开始开发实际的客户需求。在 2-3 个月内,产品已准备好交付。所以到目前为止,在 ASP.NET 和 Oracle 11g 上一切正常。当我们进行部署和 UAT 时,我们了解到客户正在为他现有的 ERP 使用 oracle 9i,这与我们开发的版本不匹配。因此,我们在 Internet 上搜索以验证同一 ODAC 提供程序是否与 Oracle 9i 兼容。我们找到了提到它与 Oracle 9i 兼容的参考资料。
我们刚刚将数据库迁移到Oracle 9i服务器,相应地更改EF模型,发现以下问题:
1.交易未自动提交!
using (TransactionScope transaction = new TransactionScope())
{
// some code written here
}
相同的代码在 11g 中运行,但在移至 Oracle 9i 时停止运行。在 using 语句完成后,事务不会自动提交。我们故意在 using 块中写了transaction.commit();,它开始工作了。
这是预期的行为吗?
2。 VARCHAR2 数据类型和 ODP NET 提供程序存在问题。
我们在以Varchar2 和其他数据库类型作为参数的数据库中创建了一些存储过程。在使用 ADO.NET 样式 (OracleConnection, OracleCommand 和 OracleParameter) 访问这些存储过程时,我们了解到具有 VARCHAR2 数据类型的参数有时会截断数据,即使数据传递给参数的大小小于给定的表格列。它只是从末尾随机删除字符数。
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);
从那时起它就开始工作了。
考虑到以上问题,
- 我无法以通常的方式从 ASP.NET 调用存储过程 (CommandType.StoredProcedure) #problem-1 在上面
- 插入或更新后,我无法从存储过程返回任何数据或标量值或返回值。上面的#problem-3
- 我无法在代码级别使用事务。 (它一直说,分布式事务已初始化,但实际上我根本没有分布式事务!)
为什么要在上线后结束所有上述内容? 我已经解决了一个月,一个接一个地解决了 Oracle 的问题,这几乎是噩梦,这让我思考
ODP.NET/ODAC工具真的靠谱吗?
如果不是,那么根据您的经验,我可以选择哪些其他选择? (请注意 ODBC 在 Oracle 9i 中也存在类似问题)。
我更有可能在下周从事类似的项目,我想这次我想以更好的方法做好准备。
【问题讨论】:
-
不支持 Oracle 9i。不应针对它开发新的应用程序。
-
你应该把你的问题分成几部分。这个问题无法回答。
标签: .net oracle oracle11g odp.net oracle9i