代码改变世界

WebMatrix之改造WebMatrix.Data

2012-04-04 23:54  Ecin  阅读(837)  评论(0编辑  收藏  举报

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数据访问系列演示代码下载此处