65.9K
CodeProject 正在变化。 阅读更多。
Home

SQL Server 存储过程的包装生成器

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.46/5 (20投票s)

2004年7月1日

2分钟阅读

viewsIcon

153528

downloadIcon

3688

一个实用程序,用于生成包装存储过程的 .NET 代码。

Sample Image - SPGenerator.png

引言

最近我厌倦了一遍又一遍地重写相同的代码。 在我的例子中,它是访问 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 峰值。
  • 2004 年 7 月 2 日
    • 修复了 jobr1ch 指出的一个错误,即为名称中带有空格的存储过程生成了不正确的方法名称。 现在,空格将替换为下划线字符。 因此,“Sales By Year”变为“Sales_By_Year”。 感谢您指出这一点 jobr1ch :)。
    • 按名称对存储过程进行了排序。
© . All rights reserved.