WebMatrix数据访问系列目录:
通过上几篇文章的介绍可以发现,WebMatrix.Data组件虽然可以跨数据库,但对存储过程的访问是不支持的,下面我们就来改造WebMatrix.Data,实现对存储过程的访问,使之成为一个真正意义上的Universal Database Access Components。
直接上代码:
public partial class Database { internal IEnumerable<dynamic> QueryWithProcedure(string procedureName, IEnumerable<DbParameter> parameters) { EnsureConnectionOpen(); DbCommand command = Connection.CreateCommand(); command.CommandType = CommandType.StoredProcedure; command.CommandText = procedureName; AddParameters(command, parameters); using (command) { IEnumerable<string> columnNames = null; using (DbDataReader reader = command.ExecuteReader()) { foreach (DbDataRecord record in reader) { if (columnNames == null) { columnNames = GetColumnNames(record); } yield return new DynamicRecord(columnNames, record); } } } } internal int ExecuteWithProcedure(string procedureName, IEnumerable<DbParameter> parameters) { EnsureConnectionOpen(); DbCommand command = Connection.CreateCommand(); command.CommandType = CommandType.StoredProcedure; command.CommandText = procedureName; AddParameters(command, parameters); using (command) { return command.ExecuteNonQuery(); } } internal dynamic QueryValueWithProcedure(string procedureName, IEnumerable<DbParameter> parameters) { EnsureConnectionOpen(); DbCommand command = Connection.CreateCommand(); command.CommandType = CommandType.StoredProcedure; command.CommandText = procedureName; AddParameters(command, parameters); using (command) { return command.ExecuteScalar(); } } private static void AddParameters(DbCommand command, IEnumerable<DbParameter> parameters) { if (parameters == null) return; foreach (var p in parameters) { command.Parameters.Add(p); } } /// <summary> /// specify a procedure to query records. /// </summary> /// <param name="procedureName"></param> /// <param name="parameters"></param> /// <returns></returns> public IEnumerable<dynamic> Query(string procedureName, Func<IEnumerable<DbParameter>> parameters ) { if (String.IsNullOrEmpty(procedureName)) { throw ExceptionHelper.CreateArgumentNullOrEmptyException("procedureName"); } return QueryWithProcedure(procedureName, parameters == null ? null : parameters()); } /// <summary> /// specify a procedure to query one record. /// </summary> /// <param name="procedureName"></param> /// <param name="parameters"></param> /// <returns></returns> public dynamic QuerySingle(string procedureName, Func<IEnumerable<DbParameter>> parameters) { if (String.IsNullOrEmpty(procedureName)) { throw ExceptionHelper.CreateArgumentNullOrEmptyException("procedureName"); } return Query(procedureName,parameters).FirstOrDefault(); } /// <summary> /// specify a procedure to execute data logic. /// </summary> /// <param name="procedureName"></param> /// <param name="parameters"></param> /// <returns></returns> public int Execute(string procedureName, Func<IEnumerable<DbParameter>> parameters ) { if (String.IsNullOrEmpty(procedureName)) { throw ExceptionHelper.CreateArgumentNullOrEmptyException("procedureName"); } return ExecuteWithProcedure(procedureName, parameters == null ? null : parameters()); } /// <summary> /// specify a procedure to query value. /// </summary> /// <param name="procedureName"></param> /// <param name="parameters"></param> /// <returns></returns> public dynamic QueryValue(string procedureName, Func<IEnumerable<DbParameter>> parameters) { if (String.IsNullOrEmpty(procedureName)) { throw ExceptionHelper.CreateArgumentNullOrEmptyException("procedureName"); } return QueryValueWithProcedure(procedureName, parameters == null ? null : parameters()); } }
改造后使用方法如下,我使用的是ODP.NET:
static void TestExtesionWithOracle() { var db = Database.Open("myoracle"); var insert_result = db.Execute("PCK_SYSDICT.insert_data", () => new List<OracleParameter>() { new OracleParameter("p_dict_name", OracleDbType.Varchar2,"testdb123",ParameterDirection.Input), new OracleParameter("p_dict_name", OracleDbType.Varchar2,"123333",ParameterDirection.Input), new OracleParameter("p_dict_name", OracleDbType.Varchar2,"this is my test dict table",ParameterDirection.Input) }); var data = db.Query("PCK_SYSDICT.GET_ALL_DATA", () => new List<OracleParameter>() { new OracleParameter("p_cur", OracleDbType.RefCursor,DBNull.Value,ParameterDirection.Output) }); foreach (var item in data) { Console.WriteLine("DICT_NAME:{0},VALUE:{1},DES:{2}", item.DICT_NAME, item.VALUE, item.DES); } }
使用的package 头如下:
create or replace package PCK_SYSDICT is type rowset IS REF CURSOR; PROCEDURE get_all_data(p_cur OUT NOCOPY rowset); PROCEDURE get_one_data(p_dict_id IN NUMBER, p_cur OUT rowset); PROCEDURE insert_data(p_dict_name IN VARCHAR2, p_value IN VARCHAR2, p_des in VARCHAR2); end PCK_SYSDICT;
WebMatrix数据访问系列演示代码下载此处。