【问题标题】:How do I call a stored procedure from NHibernate that has no result?如何从 NHibernate 调用没有结果的存储过程?
【发布时间】:2009-07-07 10:21:24
【问题描述】:

我有一个记录一些数据的存储过程,如何使用 NHibernate 调用它?

到目前为止我有:

ISession session = ....
IQuery query = session.CreateQuery("exec LogData @Time=:time @Data=:data");
query.SetDateTime("time", time);
query.SetString("data", data);
query.?????;

????? 方法应该是什么?还是在做一些更根本的错误?

【问题讨论】:

    标签: c# nhibernate stored-procedures


    【解决方案1】:

    SQL Query 上的 ExecuteUpdate 应该会对您有所帮助。

    示例:

    ISession session = ....
    IQuery query = session.CreateSQLQuery("exec LogData @Time=:time, @Data=:data");
    query.SetDateTime("time", time);
    query.SetString("data", data);
    query.ExecuteUpdate();
    

    【讨论】:

    • 如何获取返回值?
    【解决方案2】:

    这似乎是 NHibernate 的一个限制,来自NHibernate Documentation

    该过程必须返回一个结果集。 NHibernate 将使用 IDbCommand.ExecuteReader() 来获取结果。

    【讨论】:

    • 我不会称之为“限制”,更像是“设计”。
    【解决方案3】:

    NHibernate 允许您进行面向对象的编程,并负责在后台从数据库中获取对象并将对象保存到数据库中。

    NHibernate 没有为您提供简单的 API 来简单地执行存储过程,因为这似乎与面向对象编程没有太大关系,无论是获取对象还是保存它们。

    因此,在尝试直接使用 NHibernate 执行高度程序化的代码时,您在做一些根本错误的事情。如果你想使用 NHibernate,你必须告诉它在后台执行这个存储过程将如何神奇地帮助从数据库中获取对象并将对象保存到数据库中。

    你可以:

    • 直接使用 ADO.NET,打开新的IDbConnection 或获取ISession 的连接,创建IDbCommand 等。如果您需要一次性方法来执行存储过程,请执行此操作。李>
    • 创建一个 NHibernate 监听器并在Configuration 中配置它,以便在通过 NHibernate 管道发送某些其他事件时执行此存储过程。仅当此存储过程每次都应实际执行且仅在这些事件发生时才执行此操作。

    【讨论】:

      【解决方案4】:

      您可以使用 UniqueResult 来执行不返回任何内容的存储过程。我正在使用以下方法调用存储过程,该过程可以插入或更新记录以跟踪当前登录到我们的 ASP.NET MVC 站点的用户。

      IQuery query = session.GetNamedQuery("UserSession_Save");
      query.SetInt32("UserID", userID);
      query.SetString("CookieID", cookieID);
      query.SetString("Controller", controller);
      query.SetString("Action", action);
      
      query.UniqueResult();
      

      【讨论】:

      • 在我确保正确构建了带有参数的存储过程之后,两者都对我有用。
      【解决方案5】:

      一般来说,调用一个执行一些其他杂务并在最后返回结果集的过程与进行SELECT 查询没有什么不同。因此,在上面的答案中,在最后一步执行查询时,您需要调用

      query.List<T>();

      其中T 是在您的代码中定义的 POCO 对象。

      【讨论】:

        【解决方案6】:

        执行以下解决方案:

        public void Test(TestEntity TestEntity)
                {           
          IQuery query = NHSession.CreateSQLQuery("exec LogData :Time, :Data");
                    query.SetParameter("Time", TestEntity.Time);
                    query.SetParameter("Data", TestEntity.Data);
                    object obj = query.UniqueResult();
                }
        

        【讨论】:

          【解决方案7】:

          存储过程必须返回结果集。过程的第一个参数必须是返回结果集的 OUT。这是通过在 Oracle 9i 或更高版本中使用 SYS_REFCURSOR 类型来完成的。即使您不想返回任何结果集,也必须将存储过程中的第一个参数声明为 CURSOR_NAME OUT SYS_REFCURSOR

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2015-12-21
            相关资源
            最近更新 更多