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