如何使用NHibernate 2.1为插入存储过程构建映射文件

时间:2009-08-21 17:18:55

标签: nhibernate stored-procedures

我正在寻找一种使用NHibernate 2.1映射简单插入存储过程的方法

我发现的大多数示例都是从sproc中获取数据 - 但我要做的是使用存储过程插入像记录一样的审计。但我更愿意为此

构建一个映射文件

另外 - 要清楚我不打算像下面那样构建一个实体+映射文件。相反,我想看看我是否可以简单地将params映射到单个xml文件中,并使用会话对象通过“CreateSQLQuery”调用它

<class name="Staff, SampleApplication.Library" table="Staff">  
    <id name="Id" column="Id" type="Int32">  
      <generator class="native" />  
    </id>  
    <property name="LastName" column="LastName" type="String" length="255"/>  
    <property name="FirstName" column="FirstName" type="String" length="255"/>  
    <property name="EmailAddress" column="EmailAddress" type="String" length="512"/>  

    <sql-insert>EXEC InsertStaff ?,?,?</sql> 
</class>

1 个答案:

答案 0 :(得分:2)

顾名思义,CreateSQLQuery用于查询,而不是用于插入/更新/删除。调用你描述的那种sproc是可能的,但不能通过任何NHibernate支持的查询机制调用AFAIK。

sproc本身可以通过<database-object>标签包含在映射文件中。以下示例适用于Sql Server:

<database-object>
  <create>
    <![CDATA[
      go
      create procedure dbo.SetFooBar
        @Foo nvarchar(32)
        @Bar nvarchar(32)
      as
      begin
        ...
      end
      go
    ]]>
  </create>
  <drop>
    <![CDATA[
      if object_id (N'dbo.SetFooBar', N'P') is not null
        drop procedure dbo.SetFooBar;
      go
    ]]>
  </drop>
</database-object>

然后您的代码可以调用sproc。这是通过让NHibernate为你创建一个IDbCommand,用参数填充它,并以通常的ADO.NET方式调用它的ExecuteNonQuery方法来完成的:

private void SetFooBar(ISession session, string foo, string bar)
{
  var connection = session.Connection;
  var implementor = session.GetSessionImplementation();
  var driver = implementor.Factory.ConnectionProvider.Driver;
  var command = driver.GenerateCommand(CommandType.StoredProcedure, 
                  new global::NHibernate.SqlCommand.SqlString("SetFooBar"), 
                  new global::NHibernate.SqlTypes.SqlType[] {
                    global::NHibernate.SqlTypes.SqlTypeFactory.GetString(32),
                    global::NHibernate.SqlTypes.SqlTypeFactory.GetString(32),
                  });

  command.Connection = connection;

  SetParameter(command, 0, "@Foo", foo);
  SetParameter(command, 1, "@Bar", foo);

  command.ExecuteNonQuery();
}

private void SetParameter(IDbCommand cmd, int index, string name, object value)
{
  IDataParameter param = (IDataParameter) cmd.Parameters[index];

  param.ParameterName = name;
  param.Value = value;
}