现在的位置: 首页 > 综合 > 正文

在nhibernate中执行SQL语句和存储过程

2014年03月18日 ⁄ 综合 ⁄ 共 2864字 ⁄ 字号 评论关闭
在nhibernate中执行SQL语句和存储过程

在有些时候,可能需要直接执行SQL语句、存储过程等,但nhibernate并没有提供一种让我们执行SQL语句的方法,不过可以通过一些间接的方法来实现。 1. IDriver接口 IDriver接口就是数据访问的驱动器,对于不同的数据提供者(SqlClient, OleDb等)就有不同的驱动器,与SqlClient对应的是SqlClientDriver, 而与OleDb对应的就是OleDbDriver。 IDriver接口用于取得连接对象,命令对象,并且格式化命令文本。 2. 取得数据库连接对象 要执行SQL,必须取得IDbConnection对象,它可以通过会话工厂取得。要注意的是ISessionFactory接口并没有提供与连接对象相关的操作,这些操作由ISessionFactoryImplementor接口定义。 ISessionFactoryImplementor继承自ISessionFactory,而会话工厂的实现类SessionFactoryImpl实现了这两个接口。 取得连接对象的代码如下: ISessionFactoryImplementor factory = (ISessionFactoryImplementor)cfg.BuildSessionFactory(); IDbConnection conn = factory.OpenConnection(); OpenConnection方法从连接提供者ConnectionProvider取得IDbConnection对象,而连接提供者通过Driver对象创建IDbConnection。 3. 获得IDbCommand对象 在nhibernate内部,数据操作都是通过IDbCommand对象完成的,使用Command对象可以防止注入式攻击和处理一些特殊字符。 取得IDbCommand对象的代码下: IDbCommand cmd = factory.ConnectionProvider.Driver.CreateCommand(); 可能有人会问,直接new SqlCommand()不就可以啦(如果使用SqlClient的话里有话),干吗这么复杂? 没错,这样确实是可以的,nhibernate内部也是这样做的。但如果我们直接这样做的话,那代码就没有很好的移植性,如果改变数据库连接方式,那么就需要更改代码了,而使用上面的代码则不需求更改任何代码。当然,SQL语句除外。 至于参数,通过IDbCommand.CreateParameter就可以处理了,这里就不多说了。 4. 示例 下面给出一个在nhibernate中执行SQL语句的方法ExecuteSQL。

 

public IList ExecuteSQL( string query ) {    IList result = new ArrayList();    ISessionFactoryImplementor s = (ISessionFactoryImplementor)cfg.BuildSessionFactory();    IDbCommand cmd = s.ConnectionProvider.Driver.CreateCommand();    cmd.CommandText = query;    IDbConnection conn = s.OpenConnection();    try {       cmd.Connection = conn;       IDataReader rs = cmd.ExecuteReader();       while ( rs.Read() ) {          int fieldCount = rs.FieldCount;          object[] values = new Object[ fieldCount ];          for ( int i = 0; i < fieldCount; i ++ )             values[i] = rs.GetValue(i);          result.Add( values );       }    }    finally {       s.CloseConnection(conn);    }    return result; } 执行存储过程的方法.

 

public IList ExecuteStoredProc( string spName, ICollection paramInfos ) {    IList result = new ArrayList();    ISessionFactoryImplementor s = (ISessionFactoryImplementor)cfg.BuildSessionFactory();    IDbCommand cmd = s.ConnectionProvider.Driver.CreateCommand();    cmd.CommandText = spName;    cmd.CommandType = CommandType.StoredProcedure;    // 加入参数    if ( paramInfos != null ) {       foreach( ParamInfo info in paramInfos ) {          IDbDataParameter parameter = cmd.CreateParameter();          parameter.ParameterName = info.name; // driver.FormatNameForSql( info.Name );          parameter.Value = info.Value;          cmd.Parameters.Add( parameter );       }    }    IDbConnection conn = s.OpenConnection();    try {       cmd.Connection = conn;       IDataReader rs = cmd.ExecuteReader();       while ( rs.Read() ) {          int fieldCount = rs.FieldCount;          object[] values = new Object[ fieldCount ];          for ( int i = 0; i < fieldCount; i ++ )             values[i] = rs.GetValue(i);          result.Add( values );       }    }    finally {       s.CloseConnection(conn);    }    return result; }

 

其中ParamInfo为存储参数信息的结构, 定义如下:  public struct ParamInfo {     public string Name;     public object Value;  } 返回结果与nhibernate的query的结果保存一致(返回object[]的情况)。

抱歉!评论已关闭.