|
Posted on
2004-08-09 21:52
Wintle
阅读( 4030)
评论()
编辑
收藏
举报
微软提供的Microsoft Application Blocks for .NET 中的Data Access V2.0 相比之前的V1.0有了很大的性能提升,基于它可以开发高性能和伸缩性的.Net数据库应用系统。但Data Access V2.0毕竟是一个通用性的代码,要适应实际应用系统的开发,还需要进行一定的个性化。
我们在做应用系统时,采用了(DataAccess + DAL + Model + BLL + PRES)的结构,与Sql Server打交道的方式一致采用DataAccess执行数据库存储过程来实现。
那么,个性化的需求即可以大致定义为:
统一暴露执行各种存储过程的静态方法。
连接字符串内部化,不在调用过程中定置。(这一点很重要,每次调用都设定的弊端不言而明)。
连接字符串应该是加密的。因此在读取的时候,要解密。
能高效利用Data Access V2.0提供的参数缓存支持。
在这些原则下,我们改进出如下的Data Access , 希望高
微软提供的Microsoft Application Blocks for .NET 中的Data Access V2.0 相比之前的V1.0有了很大的性能提升,基于它可以开发高性能和伸缩性的.Net数据库应用系统。但Data Access V2.0毕竟是一个通用性的代码,要适应实际应用系统的开发,还需要进行一定的个性化。
我们在做应用系统时,采用了(DataAccess + DAL + Model + BLL + PRES)的结构,与Sql Server打交道的方式一致采用DataAccess执行数据库存储过程来实现。
那么,个性化的需求即可以大致定义为:
- 统一暴露执行各种存储过程的静态方法。
- 连接字符串内部化,不在调用过程中定置。(这一点很重要,每次调用都设定的弊端不言而明)。
- 连接字符串应该是加密的。因此在读取的时候,要解密。
- 能高效利用Data Access V2.0提供的参数缓存支持。
在这些原则下,我们改进出如下的Data Access , 希望高手不吝指正!
// =============================================================================== // 来源于 Microsoft Data Access Application Block for .NET 2.0 // 修改者 Wintle // 修改时间 2004年4月20日 // 修订: // Wintle,040805 // 将AssignParameterValues()public化,对外提供public static bool GetCachedParameterSet(string connectionString,string spName,out SqlParameter[] parms)方法 // 使CodePlus生成的代码可以直接智能缓存。 // 内部版本: 1.1 // ===============================================================================
using System; using System.Data; using System.Configuration; using System.Xml; using System.Data.SqlClient; using System.Collections;
namespace DataAccess { /**//// <summary> /// 数据访问层,提供处理Sql Server 2000数据库的各种方法 /// </summary> public sealed class Database { private utility methods & constructors#region private utility methods & constructors
private Database() {}
/**//// <summary> /// 取回连接字符串 /// </summary> public static string ConnectionString { get {return ConnectionInfo.DecryptDBConnectionString(ConfigurationSettings.AppSettings["ConnectionString"]) ;} } private static void AttachParameters(SqlCommand command, SqlParameter[] commandParameters); private static void AssignParameterValues(SqlParameter[] commandParameters, DataRow dataRow); /**//// <summary> /// 在object[] 前加了params 使可多个直接添入。改成public了。 /// </summary> public static void AssignParameterValues(SqlParameter[] commandParameters,params object[] parameterValues); private static void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, out bool mustCloseConnection ); #endregion private utility methods & constructors
ExecuteNonQuery#region ExecuteNonQuery
public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText); public static int ExecuteNonQuery(string connectionString, string spName, params object[] parameterValues); public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText); public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters); public static int ExecuteNonQuery(SqlConnection connection, string spName, params object[] parameterValues); public static int ExecuteNonQuery(SqlTransaction transaction, CommandType commandType, string commandText); public static int ExecuteNonQuery(SqlTransaction transaction, string spName, params object[] parameterValues); #endregion ExecuteNonQuery
public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText) 这里省略了,因为和ExecuteNonQuery结构都一样了。 进入正题: RunProc#region RunProc
/**//// <summary> /// 执行一个没有参数的,只返回影响行数的存储过程。(注意,不能接收return value) /// </summary> /// <param name="procName"></param> /// <returns></returns> public static int RunProc(string procName) { return ExecuteNonQuery(Database.ConnectionString,CommandType.StoredProcedure,procName,(SqlParameter[])null); }
/**//// <summary> /// 执行一个带参数的,只返回影响行数的存储过程。(注意,不能接收return value) /// </summary> /// <param name="procName"></param> /// <param name="prams"></param> /// <returns></returns> public static int RunProc(string procName,SqlParameter[] prams) { return ExecuteNonQuery(Database.ConnectionString,CommandType.StoredProcedure,procName,prams); } /**//// <summary> /// 执行一个不带参数的,返回SqlDataReader的存储过程。 /// </summary> /// <param name="procName"></param> /// <returns></returns> public static void RunProc(string procName,out SqlDataReader reader) { reader = ExecuteReader(Database.ConnectionString,CommandType.StoredProcedure,procName,(SqlParameter[])null); }
/**//// <summary> /// 执行一个带参数的,返回SqlDataReader的存储过程。 /// </summary> /// <param name="procName"></param> /// <param name="prams"></param> /// <returns></returns> public static void RunProc(string procName,SqlParameter[] prams,out SqlDataReader reader) { reader = ExecuteReader(Database.ConnectionString,CommandType.StoredProcedure,procName,prams); }
/**//// <summary> /// 执行一个不带参数的,返回DataSet的存储过程。 /// </summary> /// <param name="procName"></param> /// <returns></returns> public static void RunProc(string procName,out DataSet ds) { ds = ExecuteDataset(Database.ConnectionString,CommandType.StoredProcedure,procName,(SqlParameter[])null); }
/**//// <summary> /// 执行一个带参数的,返回DataSet的存储过程。 /// </summary> /// <param name="procName"></param> /// <param name="prams"></param> /// <returns></returns> public static void RunProc(string procName,SqlParameter[] prams,out DataSet ds) { ds = ExecuteDataset(Database.ConnectionString,CommandType.StoredProcedure,procName,prams); }
/**//// <summary> /// 执行一个不带参数的,返回结果集第一行第一列的数据。为object型,通过类型强制转换得到。 /// 例如 System.Datetime dt = (System.Datetime)RunProc("GetDate"); /// </summary> /// <param name="procName">存储过程名称</param> /// <returns></returns> public static void RunProc(string procName,out object obj) { obj = ExecuteScalar(Database.ConnectionString,CommandType.StoredProcedure,procName,(SqlParameter[])null); }
/**//// <summary> /// 执行一个带参数的,返回结果集第一行第一列的数据。为object型,通过类型强制转换得到。 /// 例如 System.Datetime dt = (System.Datetime)RunProc("GetDate"); /// </summary> /// <param name="procName"></param> /// <param name="prams"></param> /// <returns></returns> public static void RunProc(string procName,SqlParameter[] prams,out object obj) { obj = ExecuteScalar(Database.ConnectionString,CommandType.StoredProcedure,procName,prams); }
/**//// <summary> /// 执行一个不带参数的,返回xmlReader结果集的存储过程。 /// </summary> /// <param name="procName"></param> /// <returns></returns> public static void RunProc(string procName,out XmlReader xmlReader) { xmlReader = ExecuteXmlReader(new SqlConnection(Database.ConnectionString),CommandType.StoredProcedure,procName,(SqlParameter[])null); }
/**//// <summary> /// 执行一个带参数的,返回xmlReader结果集的存储过程。 /// </summary> /// <param name="procName"></param> /// <param name="prams"></param> /// <returns></returns> public static void RunProc(string procName,SqlParameter[] prams,out XmlReader xmlReader) { xmlReader = ExecuteXmlReader(new SqlConnection(Database.ConnectionString),CommandType.StoredProcedure,procName,prams); }
#endregion
Make SqlParameters#region Make SqlParameters /**//// <summary> /// Make input param. /// </summary> /// <param name="ParamName">Name of param.</param> /// <param name="DbType">Param type.</param> /// <param name="Size">Param size.</param> /// <param name="Value">Param value.</param> /// <returns>New parameter.</returns> public static SqlParameter MakeInParam(string ParamName, SqlDbType DbType, int Size, object Value) { return MakeParam(ParamName, DbType, Size, ParameterDirection.Input, Value); }
/**//// <summary> /// Make input param. /// </summary> /// <param name="ParamName">Name of param.</param> /// <param name="DbType">Param type.</param> /// <param name="Size">Param size.</param> /// <returns>New parameter.</returns> public static SqlParameter MakeOutParam(string ParamName, SqlDbType DbType, int Size) { return MakeParam(ParamName, DbType, Size, ParameterDirection.Output, null); }
/**//// <summary> /// Make stored procedure param. /// </summary> /// <param name="ParamName">Name of param.</param> /// <param name="DbType">Param type.</param> /// <param name="Size">Param size.</param> /// <param name="Direction">Parm direction.</param> /// <param name="Value">Param value.</param> /// <returns>New parameter.</returns> public static SqlParameter MakeParam(string ParamName, SqlDbType DbType, Int32 Size, ParameterDirection Direction, object Value) { SqlParameter param;
if(Size > 0) param = new SqlParameter(ParamName, DbType, Size); else param = new SqlParameter(ParamName, DbType);
param.Direction = Direction; if (!(Direction == ParameterDirection.Output && Value == null)) param.Value = Value;
return param; } #endregion
} /**//// <summary> /// 用来存取缓存SqlParameter[] /// </summary> public sealed class ParamsCache { private methods, variables, and constructors#region private methods, variables, and constructors
private ParamsCache() {}
private static Hashtable paramCache = Hashtable.Synchronized(new Hashtable()); private static SqlParameter[] DiscoverSpParameterSet(SqlConnection connection, string spName, bool includeReturnValueParameter) private static SqlParameter[] CloneParameters(SqlParameter[] originalParameters); public static void CacheParameterSet(string connectionString, string commandText, params SqlParameter[] commandParameters); public static SqlParameter[] GetCachedParameterSet(string connectionString, string commandText)
/**//// <summary> /// 得到缓存中的存储过程参数。如果能得到,返回true,并out 参数出来,不能得到,则parms = null,返回false; /// 作者:Wintle:) 这样写是为了在外面好调用,直接判断是不是有缓存。然后进行相应操作。 /// </summary> /// <param name="connectiongString"></param> /// <param name="spName"></param> /// <param name="parms"></param> /// <returns></returns> public static bool GetCachedParameterSet(string connectionString,string spName,out SqlParameter[] parms) { bool hasCached = false; if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); string hashKey = connectionString + ":" + spName;
SqlParameter[] cachedParameters = paramCache[hashKey] as SqlParameter[]; if (cachedParameters == null) { parms = null; } else { parms = CloneParameters(cachedParameters); hasCached = true; } return hasCached; }
#endregion caching functions 下面是取回存储过程参数的代码了,略去。 }
// =============================================================================== // 来源于 Microsoft Data Access Application Block for .NET 2.0 // 修改者 Wintle // 修改时间 2004年4月20日 // 修订: // Wintle,040805 // 将AssignParameterValues()public化,对外提供public static bool GetCachedParameterSet(string connectionString,string spName,out SqlParameter[] parms)方法 // 使CodePlus生成的代码可以直接智能缓存。 // 内部版本: 1.1 // ===============================================================================
using System; using System.Data; using System.Configuration; using System.Xml; using System.Data.SqlClient; using System.Collections;
namespace DataAccess { /**//// <summary> /// 数据访问层,提供处理Sql Server 2000数据库的各种方法 /// </summary> public sealed class Database { private utility methods & constructors#region private utility methods & constructors
private Database() {}
/**//// <summary> /// 取回连接字符串 /// </summary> public static string ConnectionString { get {return ConnectionInfo.DecryptDBConnectionString(ConfigurationSettings.AppSettings["ConnectionString"]) ;} } private static void AttachParameters(SqlCommand command, SqlParameter[] commandParameters); private static void AssignParameterValues(SqlParameter[] commandParameters, DataRow dataRow); /**//// <summary> /// 在object[] 前加了params 使可多个直接添入。改成public了。 /// </summary> public static void AssignParameterValues(SqlParameter[] commandParameters,params object[] parameterValues); private static void PrepareCommand(SqlCommand command, SqlConnection connection, SqlTransaction transaction, CommandType commandType, string commandText, SqlParameter[] commandParameters, out bool mustCloseConnection ); #endregion private utility methods & constructors
ExecuteNonQuery#region ExecuteNonQuery
public static int ExecuteNonQuery(string connectionString, CommandType commandType, string commandText); public static int ExecuteNonQuery(string connectionString, string spName, params object[] parameterValues); public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText); public static int ExecuteNonQuery(SqlConnection connection, CommandType commandType, string commandText, params SqlParameter[] commandParameters); public static int ExecuteNonQuery(SqlConnection connection, string spName, params object[] parameterValues); public static int ExecuteNonQuery(SqlTransaction transaction, CommandType commandType, string commandText); public static int ExecuteNonQuery(SqlTransaction transaction, string spName, params object[] parameterValues); #endregion ExecuteNonQuery
public static DataSet ExecuteDataset(string connectionString, CommandType commandType, string commandText) 这里省略了,因为和ExecuteNonQuery结构都一样了。 进入正题: RunProc#region RunProc
/**//// <summary> /// 执行一个没有参数的,只返回影响行数的存储过程。(注意,不能接收return value) /// </summary> /// <param name="procName"></param> /// <returns></returns> public static int RunProc(string procName) { return ExecuteNonQuery(Database.ConnectionString,CommandType.StoredProcedure,procName,(SqlParameter[])null); }
/**//// <summary> /// 执行一个带参数的,只返回影响行数的存储过程。(注意,不能接收return value) /// </summary> /// <param name="procName"></param> /// <param name="prams"></param> /// <returns></returns> public static int RunProc(string procName,SqlParameter[] prams) { return ExecuteNonQuery(Database.ConnectionString,CommandType.StoredProcedure,procName,prams); } /**//// <summary> /// 执行一个不带参数的,返回SqlDataReader的存储过程。 /// </summary> /// <param name="procName"></param> /// <returns></returns> public static void RunProc(string procName,out SqlDataReader reader) { reader = ExecuteReader(Database.ConnectionString,CommandType.StoredProcedure,procName,(SqlParameter[])null); }
/**//// <summary> /// 执行一个带参数的,返回SqlDataReader的存储过程。 /// </summary> /// <param name="procName"></param> /// <param name="prams"></param> /// <returns></returns> public static void RunProc(string procName,SqlParameter[] prams,out SqlDataReader reader) { reader = ExecuteReader(Database.ConnectionString,CommandType.StoredProcedure,procName,prams); }
/**//// <summary> /// 执行一个不带参数的,返回DataSet的存储过程。 /// </summary> /// <param name="procName"></param> /// <returns></returns> public static void RunProc(string procName,out DataSet ds) { ds = ExecuteDataset(Database.ConnectionString,CommandType.StoredProcedure,procName,(SqlParameter[])null); }
/**//// <summary> /// 执行一个带参数的,返回DataSet的存储过程。 /// </summary> /// <param name="procName"></param> /// <param name="prams"></param> /// <returns></returns> public static void RunProc(string procName,SqlParameter[] prams,out DataSet ds) { ds = ExecuteDataset(Database.ConnectionString,CommandType.StoredProcedure,procName,prams); }
/**//// <summary> /// 执行一个不带参数的,返回结果集第一行第一列的数据。为object型,通过类型强制转换得到。 /// 例如 System.Datetime dt = (System.Datetime)RunProc("GetDate"); /// </summary> /// <param name="procName">存储过程名称</param> /// <returns></returns> public static void RunProc(string procName,out object obj) { obj = ExecuteScalar(Database.ConnectionString,CommandType.StoredProcedure,procName,(SqlParameter[])null); }
/**//// <summary> /// 执行一个带参数的,返回结果集第一行第一列的数据。为object型,通过类型强制转换得到。 /// 例如 System.Datetime dt = (System.Datetime)RunProc("GetDate"); /// </summary> /// <param name="procName"></param> /// <param name="prams"></param> /// <returns></returns> public static void RunProc(string procName,SqlParameter[] prams,out object obj) { obj = ExecuteScalar(Database.ConnectionString,CommandType.StoredProcedure,procName,prams); }
/**//// <summary> /// 执行一个不带参数的,返回xmlReader结果集的存储过程。 /// </summary> /// <param name="procName"></param> /// <returns></returns> public static void RunProc(string procName,out XmlReader xmlReader) { xmlReader = ExecuteXmlReader(new SqlConnection(Database.ConnectionString),CommandType.StoredProcedure,procName,(SqlParameter[])null); }
/**//// <summary> /// 执行一个带参数的,返回xmlReader结果集的存储过程。 /// </summary> /// <param name="procName"></param> /// <param name="prams"></param> /// <returns></returns> public static void RunProc(string procName,SqlParameter[] prams,out XmlReader xmlReader) { xmlReader = ExecuteXmlReader(new SqlConnection(Database.ConnectionString),CommandType.StoredProcedure,procName,prams); }
#endregion
Make SqlParameters#region Make SqlParameters /**//// <summary> /// Make input param. /// </summary> /// <param name="ParamName">Name of param.</param> /// <param name="DbType">Param type.</param> /// <param name="Size">Param size.</param> /// <param name="Value">Param value.</param> /// <returns>New parameter.</returns> public static SqlParameter MakeInParam(string ParamName, SqlDbType DbType, int Size, object Value) { return MakeParam(ParamName, DbType, Size, ParameterDirection.Input, Value); }
/**//// <summary> /// Make input param. /// </summary> /// <param name="ParamName">Name of param.</param> /// <param name="DbType">Param type.</param> /// <param name="Size">Param size.</param> /// <returns>New parameter.</returns> public static SqlParameter MakeOutParam(string ParamName, SqlDbType DbType, int Size) { return MakeParam(ParamName, DbType, Size, ParameterDirection.Output, null); }
/**//// <summary> /// Make stored procedure param. /// </summary> /// <param name="ParamName">Name of param.</param> /// <param name="DbType">Param type.</param> /// <param name="Size">Param size.</param> /// <param name="Direction">Parm direction.</param> /// <param name="Value">Param value.</param> /// <returns>New parameter.</returns> public static SqlParameter MakeParam(string ParamName, SqlDbType DbType, Int32 Size, ParameterDirection Direction, object Value) { SqlParameter param;
if(Size > 0) param = new SqlParameter(ParamName, DbType, Size); else param = new SqlParameter(ParamName, DbType);
param.Direction = Direction; if (!(Direction == ParameterDirection.Output && Value == null)) param.Value = Value;
return param; } #endregion
} /**//// <summary> /// 用来存取缓存SqlParameter[] /// </summary> public sealed class ParamsCache { private methods, variables, and constructors#region private methods, variables, and constructors
private ParamsCache() {}
private static Hashtable paramCache = Hashtable.Synchronized(new Hashtable()); private static SqlParameter[] DiscoverSpParameterSet(SqlConnection connection, string spName, bool includeReturnValueParameter) private static SqlParameter[] CloneParameters(SqlParameter[] originalParameters); public static void CacheParameterSet(string connectionString, string commandText, params SqlParameter[] commandParameters); public static SqlParameter[] GetCachedParameterSet(string connectionString, string commandText)
/**//// <summary> /// 得到缓存中的存储过程参数。如果能得到,返回true,并out 参数出来,不能得到,则parms = null,返回false; /// 作者:Wintle:) 这样写是为了在外面好调用,直接判断是不是有缓存。然后进行相应操作。 /// </summary> /// <param name="connectiongString"></param> /// <param name="spName"></param> /// <param name="parms"></param> /// <returns></returns> public static bool GetCachedParameterSet(string connectionString,string spName,out SqlParameter[] parms) { bool hasCached = false; if( connectionString == null || connectionString.Length == 0 ) throw new ArgumentNullException( "connectionString" ); if( spName == null || spName.Length == 0 ) throw new ArgumentNullException( "spName" ); string hashKey = connectionString + ":" + spName;
SqlParameter[] cachedParameters = paramCache[hashKey] as SqlParameter[]; if (cachedParameters == null) { parms = null; } else { parms = CloneParameters(cachedParameters); hasCached = true; } return hasCached; }
#endregion caching functions 下面是取回存储过程参数的代码了,略去。 }
代码完。
调用DataAccess可如下代码:
public bool Create(String name,String shortName,Int32 universityId,String code) { SqlParameter[] prams = { Database.MakeInParam("@Name",System.Data.SqlDbType.VarChar,60,name), Database.MakeInParam("@ShortName",System.Data.SqlDbType.VarChar,30,shortName), Database.MakeInParam("@UniversityId",System.Data.SqlDbType.Int,4,universityId), Database.MakeInParam("@Code",System.Data.SqlDbType.VarChar,30,code) }; int reval = Database.RunProc("BSCollege_Create",prams); if(reval != -1) { return true; } else { return false; } } 如果需要缓存支持,则采用如下调用方法: public void SelectSubNodes(int universityId,int codeLength,String code,out OfficiateCollection list) { SqlDataReader reader = null; list = new OfficiateCollection(); SqlParameter[] prams; if(ParamsCache.GetCachedParameterSet(Database.ConnectionString,"BSOfficiate_SelectSubNodes",out prams)) { Database.AssignParameterValues(prams,universityId,codeLength,code); } else { prams = new SqlParameter[3]{ Database.MakeInParam("@UniversityId",System.Data.SqlDbType.Int,4,universityId), Database.MakeInParam("@CodeLength",System.Data.SqlDbType.Int,4,codeLength), Database.MakeInParam("@Code",System.Data.SqlDbType.VarChar,300,code) }; ParamsCache.CacheParameterSet(Database.ConnectionString,"BSOfficiate_SelectSubNodes",prams); } Database.RunProc("BSOfficiate_SelectSubNodes",prams,out reader); while(reader.Read()) { OfficiateInfo officiateInfo = new OfficiateInfo(); officiateInfo.ID = Int32.Parse(reader["ID"].ToString()); officiateInfo.Name = reader["Name"].ToString(); officiateInfo.Code = reader["Code"].ToString(); officiateInfo.Ordinal = Int32.Parse(reader["Ordinal"].ToString()); list.Add(officiateInfo); } reader.Close(); }
基于这个Data Access ,我们的新版 CodePlus 代码生成器 即可自动生成以上的调用代码。详情请见:
http://blog.csdn.net/wintle/archive/2004/08/09/68851.aspx
对于这个DataAccess,各位如果有什么好的建议,请告诉我,谢谢。
基于这个Data Access ,我们的新版 CodePlus 代码生成器 即可自动生成以上的调用代码。详情请见:
http://blog.csdn.net/wintle/archive/2004/08/09/68851.aspx
对于这个DataAccess,各位如果有什么好的建议,请告诉我,谢谢。
public bool Create(String name,String shortName,Int32 universityId,String code) { SqlParameter[] prams = { Database.MakeInParam("@Name",System.Data.SqlDbType.VarChar,60,name), Database.MakeInParam("@ShortName",System.Data.SqlDbType.VarChar,30,shortName), Database.MakeInParam("@UniversityId",System.Data.SqlDbType.Int,4,universityId), Database.MakeInParam("@Code",System.Data.SqlDbType.VarChar,30,code) }; int reval = Database.RunProc("BSCollege_Create",prams); if(reval != -1) { return true; } else { return false; } } 如果需要缓存支持,则采用如下调用方法: public void SelectSubNodes(int universityId,int codeLength,String code,out OfficiateCollection list) { SqlDataReader reader = null; list = new OfficiateCollection(); SqlParameter[] prams; if(ParamsCache.GetCachedParameterSet(Database.ConnectionString,"BSOfficiate_SelectSubNodes",out prams)) { Database.AssignParameterValues(prams,universityId,codeLength,code); } else { prams = new SqlParameter[3]{ Database.MakeInParam("@UniversityId",System.Data.SqlDbType.Int,4,universityId), Database.MakeInParam("@CodeLength",System.Data.SqlDbType.Int,4,codeLength), Database.MakeInParam("@Code",System.Data.SqlDbType.VarChar,300,code) }; ParamsCache.CacheParameterSet(Database.ConnectionString,"BSOfficiate_SelectSubNodes",prams); } Database.RunProc("BSOfficiate_SelectSubNodes",prams,out reader); while(reader.Read()) { OfficiateInfo officiateInfo = new OfficiateInfo(); officiateInfo.ID = Int32.Parse(reader["ID"].ToString()); officiateInfo.Name = reader["Name"].ToString(); officiateInfo.Code = reader["Code"].ToString(); officiateInfo.Ordinal = Int32.Parse(reader["Ordinal"].ToString()); list.Add(officiateInfo); } reader.Close(); }
基于这个Data Access ,我们的新版 CodePlus 代码生成器 即可自动生成以上的调用代码。详情请见:
http://blog.csdn.net/wintle/archive/2004/08/09/68851.aspx
对于这个DataAccess,各位如果有什么好的建议,请告诉我,谢谢。
基于这个Data Access ,我们的新版 CodePlus 代码生成器 即可自动生成以上的调用代码。详情请见:
http://blog.csdn.net/wintle/archive/2004/08/09/68851.aspx
对于这个DataAccess,各位如果有什么好的建议,请告诉我,谢谢。
|