SQL Server 2000C++/CLIDBAVisual Studio .NET 2003.NET 1.1Windows 2000架构师Windows XP中级开发Visual StudioSQL ServerSQLWindows.NETC#
SQL Server 存储过程的包装生成器






4.46/5 (20投票s)
2004年7月1日
2分钟阅读

153528

3688
一个实用程序,用于生成包装存储过程的 .NET 代码。
引言
最近我厌倦了一遍又一遍地重写相同的代码。 在我的例子中,它是访问 SQL Server 数据库中存储过程的代码。 我的沮丧的最终结果就是这里呈现的应用程序。
背景
在 CodeProject 上搜索发现了一篇由 leppie 描述他开发的 DBHelper
类的文章。 在试用该应用程序后,我被迷住了。 不幸的是,现有的代码库无法处理存储过程的返回值,也无法处理存储过程的输出参数。 原始文章可在此处获得。
我本可以使用 Visual Studio 中的内置支持,让它为我生成 SqlCommand
类。 然而,这种方法将数据库访问分散在整个应用程序中,并且在面对更改时非常脆弱。
我的解决方案是使用我在 leppie 的文章中看到的想法,并扩展它们来处理返回值和输出参数。
使用应用程序
要使用此应用程序,您只需将应用程序指向现有的 SQL Server,选择要为其生成包装器的存储过程,然后点击闪电符号即可。 此应用程序和所有源代码(GetSQL
类除外;有关它的信息,请参阅本文)完全免费,可用于您认为合适的任何用途。
生成的源代码
生成的代码在您为每个存储过程指定的类上提供一个静态方法。 该方法与存储过程的名称相同。 下面的示例是为单个存储过程生成的代码。 使用生成的源代码就像传入连接对象一样简单。
用户代码
private void somefunc()
{
int iRet=0;
int iNewId=0;
iRet = heatgmsm_DAL.wl_AddUser(myConn,null,"User",
"password",false,false, false,true,ref iNewId);
}
生成的代码
namespace heatgmsm
{
using System.Data;
using System.Data.SqlClient;
public class heatgmsm_DAL
{
private heatgmsm_DAL() //Private since this is never meant to be instaniated
{
}
public static int wl_AddUser(System.Data.SqlClient.SqlConnection connection,
System.Data.DataTable table, string uname, string pwd,
bool IsUserAdmin, bool IsProviderAdmin, bool IsWaitlistAdmin,
bool IsUser, ref int uid)
{
int RETURN_VALUE = 0;
System.Data.SqlClient.SqlCommand cmd = null;
System.Data.SqlClient.SqlDataReader reader = null;
if ((connection == null))
{
throw new System.ArgumentException("The connection object cannot be null");
}
else
{
if ((connection.State == System.Data.ConnectionState.Closed))
{
connection.Open();
cmd = new System.Data.SqlClient.SqlCommand("wl_AddUser",
connection);
cmd.CommandType = System.Data.CommandType.StoredProcedure;
cmd.Parameters.Add("@RETURN_VALUE",
System.Data.SqlDbType.Int, 0);
cmd.Parameters["@RETURN_VALUE"].Direction =
System.Data.ParameterDirection.ReturnValue;
cmd.Parameters["@RETURN_VALUE"].Value = RETURN_VALUE;
cmd.Parameters.Add("@uname", System.Data.SqlDbType.VarChar, 50);
cmd.Parameters["@uname"].Direction =
System.Data.ParameterDirection.Input;
cmd.Parameters["@uname"].Value = uname;
cmd.Parameters.Add("@pwd", System.Data.SqlDbType.VarChar, 50);
cmd.Parameters["@pwd"].Direction = System.Data.ParameterDirection.Input;
cmd.Parameters["@pwd"].Value = pwd;
cmd.Parameters.Add("@IsUserAdmin", System.Data.SqlDbType.Bit, 0);
cmd.Parameters["@IsUserAdmin"].Direction =
System.Data.ParameterDirection.Input;
cmd.Parameters["@IsUserAdmin"].Value = IsUserAdmin;
cmd.Parameters.Add("@IsProviderAdmin", System.Data.SqlDbType.Bit, 0);
cmd.Parameters["@IsProviderAdmin"].Direction =
System.Data.ParameterDirection.Input;
cmd.Parameters["@IsProviderAdmin"].Value = IsProviderAdmin;
cmd.Parameters.Add("@IsWaitlistAdmin", System.Data.SqlDbType.Bit, 0);
cmd.Parameters["@IsWaitlistAdmin"].Direction =
System.Data.ParameterDirection.Input;
cmd.Parameters["@IsWaitlistAdmin"].Value = IsWaitlistAdmin;
cmd.Parameters.Add("@IsUser", System.Data.SqlDbType.Bit, 0);
cmd.Parameters["@IsUser"].Direction =
System.Data.ParameterDirection.Input;
cmd.Parameters["@IsUser"].Value = IsUser;
cmd.Parameters.Add("@uid", System.Data.SqlDbType.Int, 0);
cmd.Parameters["@uid"].Direction =
System.Data.ParameterDirection.InputOutput;
cmd.Parameters["@uid"].Value = uid;
if ((table != null))
{
reader = cmd.ExecuteReader();
}
else
{
cmd.ExecuteNonQuery();
}
if (((table != null) && (reader != null)))
{
table.Clear();
table.Columns.Clear();
for (int i = 0; (i < reader.FieldCount); i = (i + 1))
{
System.Type __type;
string __name;
__type = reader.GetFieldType(i);
__name = reader.GetName(i);
table.Columns.Add(__name, __type);
}
for (; reader.Read();)
{
System.Data.DataRow row = table.NewRow();
object[] rowdata = new object[reader.FieldCount];
reader.GetValues(rowdata);
row.ItemArray = rowdata;
table.Rows.Add(row);
}
reader.Close();
}
// The Parameter @RETURN_VALUE is not an output type
// The Parameter @uname is not an output type
// The Parameter @pwd is not an output type
// The Parameter @IsUserAdmin is not an output type
// The Parameter @IsProviderAdmin is not an output type
// The Parameter @IsWaitlistAdmin is not an output type
// The Parameter @IsUser is not an output type
uid = ((int)(cmd.Parameters["@uid"].Value));
connection.Close();
RETURN_VALUE = ((int)(cmd.Parameters["@RETURN_VALUE"].Value));
return RETURN_VALUE;
}
else
{
throw new System.ArgumentException("The connection" +
" must be closed when calling this method.");
}
}
}
}
}
正如您所看到的,生成的代码量非常大,换句话说,您不再需要编写的代码。
未来方向
欢迎提出任何和所有意见、建议和/或功能请求:)。
历史
- 2004 年 7 月 1 日 -- 首次提交。
- 2004 年 7 月 1 日
- 更新为使用来自 Micheal Potter 的优秀文章中的
GetSQL
类。 这使我可以消除使用我的 *SQLUtils.dll* 辅助库。 - 在复选列表框上下文菜单中添加了刷新选项。
- 修复了应用程序空闲事件处理程序中的一个错误,该错误在复选列表框中选择项目后导致 CPU 峰值。
- 更新为使用来自 Micheal Potter 的优秀文章中的
- 2004 年 7 月 2 日
- 修复了 jobr1ch 指出的一个错误,即为名称中带有空格的存储过程生成了不正确的方法名称。 现在,空格将替换为下划线字符。 因此,“Sales By Year”变为“Sales_By_Year”。 感谢您指出这一点 jobr1ch :)。
- 按名称对存储过程进行了排序。