Fluent Nhibernate无法在包体中调用oracle存储过程

时间:2014-05-25 12:57:34

标签: c# oracle nhibernate stored-procedures fluent-nhibernate

我正在解决问题。我一直在尝试调用包体内包含的存储过程来执行。我试过没有成功。我的代码设置如下:

我的存储过程的映射文件是Mappings.hbm.xml,内容如下;

<?xml version="1.0" encoding="utf-8"?>
  <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="FAMS">
    <sql-query name="GenerateSchedule">
      { call DPRCN.Generate_Schedule ( :p_asset_id) }
    </sql-query>
</hibernate-mapping>

Global.asax文件中的Fluent Nhibernate设置如下;

private void NhibernateInitiator()
    {
        string cstring = ConfigurationManager.AppSettings["Fams"];
        SessionFactory = Fluently.Configure()
             .Database(OracleClientConfiguration.Oracle10.ConnectionString(c =>
                    c.Is(cstring))
                .Driver<NHibernate.Driver.OracleClientDriver>()
                .ShowSql())
            .Mappings(m =>
                      m.FluentMappings
                          .AddFromAssemblyOf<Asset>()
                          )
            .Mappings(m=>m.HbmMappings.AddFromAssemblyOf<Asset>())
            .ExposeConfiguration(c => c.SetProperty("current_session_context_class", "web"))
            .ExposeConfiguration(ConfigureEnvers)
            .ExposeConfiguration(cfg => new SchemaUpdate(cfg).Execute(false, true))
            .BuildSessionFactory();
    }

Oracle软件包的片段 HEADER

CREATE OR REPLACE PACKAGE DPRCN AS TYPE ReferenceCursor IS REF CURSOR; 
PROCEDURE  Generate_Schedule(pCursor OUT ReferenceCursor,p_asset_id IN Asset.asset_id%TYPE, p_regenerate IN BOOLEAN DEFAULT FALSE);

BODY

CREATE OR REPLACE PACKAGE BODY DPRCN AS
PROCEDURE Generate_Schedule(pCursor OUT ReferenceCursor,p_asset_id IN Asset.Asset_ID%TYPE,
p_regenerate IN BOOLEAN DEFAULT FALSE) AS


BEGIN
OPEN pCursor FOR
.
.
.
.

END Generate_Schedule;

当我使用下面的代码调用存储过程时,

var session = MvcApplication.SessionFactory.GetCurrentSession();
var qry = session.GetNamedQuery("DPRCN.Generate_Schedule");
                    qry.SetParameter("p_asset_id", p.assetId);
                    qry.SetParameter("p_regenerate", false);
                    qry.List();

我收到错误。以下遇到的错误摘录;

NHibernate.Exceptions.GenericADOException was caught
HResult=-2146232832
Message=could not execute query
[ { call DPRCN.Generate_Schedule ( ?) } ]
Name:p_asset_id - Value:3
[SQL: { call DPRCN.Generate_Schedule ( ?) }]
Source=NHibernate
SqlString={ call DPRCN.Generate_Schedule ( ?) }
.
.
.
InnerException: System.NotImplementedException
HResult=-2147467263
Message=OracleClientDriver does not support CallableStatement syntax (stored      procedures). 
Consider using OracleDataClientDriver instead.
Source=NHibernate
StackTrace:
at NHibernate.Driver.OracleClientDriver.OnBeforePrepare(IDbCommand command)

如果有人能够指导我前进的方向,我将很高兴。我真的被困在这里了。 感谢。

更新

我已经尝试了这个建议,我改为OracleDataClientDriver并导入了Oracle.DataAccess.dll,但该项目没有编译。在Windows 7 x64上运行。遇到错误是;

[BadImageFormatException: Could not load file or assembly 'Oracle.DataAccess' or one of its dependencies. An attempt was made to load a program with an incorrect format.]

UPDATE2 @mmjak帮助解决了初始错误,但后来又得到了一个。 NHProfiler将异常跟踪读为;

{ call DPRCN.Generate_Schedule ( 1 /* :p0 */, 0 /* :p1 */) }    Oracle.DataAccess.Client.OracleException ORA-06550: line 1, column 7:
PLS-00306: wrong number or types of arguments in call to 'GENERATE_SCHEDULE'
ORA-06550: line 1, column 7:
PL/SQL: Statement ignored    at Oracle.DataAccess.Client.OracleException.HandleErrorHelper(Int32 errCode, OracleConnection conn, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src, String procedure)
   at Oracle.DataAccess.Client.OracleException.HandleError(Int32 errCode, OracleConnection conn, String procedure, IntPtr opsErrCtx, OpoSqlValCtx* pOpoSqlValCtx, Object src)
   at Oracle.DataAccess.Client.OracleCommand.ExecuteNonQuery()
   at NHibernate.AdoNet.AbstractBatcher.ExecuteNonQuery(IDbCommand cmd)
   at NHibernate.Engine.Query.NativeSQLQueryPlan.PerformExecuteUpdate(QueryParameters queryParameters, ISessionImplementor session)

1 个答案:

答案 0 :(得分:0)

它看起来像x86和x64之间的混乱,当你使用odp.net时,这是一个肮脏但有效的解决方案:

  1. 从项目中删除引用
  2. 将oci.dll,oracle.data.access.dll,oraocie11.dll,oraops11w.dll从oracle安装文件夹复制到应用程序的bin中
  3. 添加参考&gt;浏览 - 选择以前复制的oracle.dataaccess.dll
  4. 选择copy local - true和specific version = true
  5. 在您的应用池上启用32位应用
  6. 然后您必须将connectionString更改为格式

    数据源=(DESCRIPTION =(ADDRESS =(PROTOCOL = TCP)(HOST = [地址])(PORT = 1521))(CONNECT_DATA =(SERVICE_NAME = [tns])));用户ID = [用户名];密码= [口令];