C# 单击一个按钮调用多个存储过程和GridView

C# 单击一个按钮调用多个存储过程和GridView,c#,asp.net,sql-server-2008,stored-procedures,gridview,C#,Asp.net,Sql Server 2008,Stored Procedures,Gridview,背景:我正在转换一个access运行时,它按邮政编码、计划类型和年龄搜索计划 到目前为止,,我在主搜索中正确显示了存储过程get_zip_plan_age,但不确定我是否在C#code behind中正确调用了存储过程get_lost_femal_insurance_rate,以及如何为显示最低女性的get_lost_female_rate编写不同的代码每个年龄组的比率vsget\u zip\u plan\u age显示所有数据 问题: 如何在代码隐藏中正确调用get\u lower\u fe

背景:我正在转换一个access运行时,它按邮政编码、计划类型和年龄搜索计划

到目前为止,,我在主搜索中正确显示了存储过程
get_zip_plan_age
,但不确定我是否在C#code behind中正确调用了存储过程
get_lost_femal_insurance_rate
,以及如何为显示最低女性的
get_lost_female_rate
编写不同的代码每个年龄组的比率vs
get\u zip\u plan\u age
显示所有数据

问题:

  • 如何在代码隐藏中正确调用
    get\u lower\u femal\u rate
    ?我说的对吗
  • 如何为显示每个年龄组(65、70、75、80)的最低女性比率的
    get_lower_femal_rate
    编写存储过程代码
下面是access运行时的屏幕截图:

以下是我的default.aspx.cs代码:

    protected void Search_Zip_Plan_Age_Button_Click(object sender, EventArgs e)
    {                          
        using (SqlConnection cn = new SqlConnection())
        {
            cn.ConnectionString = System.Configuration.ConfigurationManager.ConnectionStrings["PriceFinderConnectionString"].ToString();
            cn.Open();

            using (SqlCommand cmd = cn.CreateCommand())
            {
                cmd.CommandText = "get_zip_plan_age";                    
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.CommandText = "get_lowest_female_rate";
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.CommandText = "get_lowest_male_rate";
                cmd.CommandType = CommandType.StoredProcedure;

                cmd.CommandText = "get_carrier_info";
                cmd.CommandType = CommandType.StoredProcedure;


                SqlParameter parm = cmd.CreateParameter(); 
                parm.ParameterName = "@insur_age";
                parm.DbType = DbType.Int64;
                parm.Value = Convert.ToInt64(this.insur_age.Text);
                cmd.Parameters.Add(parm);

                parm = cmd.CreateParameter(); 
                parm.ParameterName = "@zip_code";
                parm.DbType = DbType.String;
                parm.Value = this.ZipCode.Text;
                cmd.Parameters.Add(parm);

                parm = cmd.CreateParameter(); 
                parm.ParameterName = "@plan_code";
                parm.DbType = DbType.String;
                parm.Value = this.PlanCode.Text;
                cmd.Parameters.Add(parm);

                SqlDataReader reader = cmd.ExecuteReader();
                Zip_Plan_Age_GridView.DataSource = reader;
                Zip_Plan_Age_GridView.DataBind();
            }
        }
    }
下面是显示所有数据的存储过程get\u zip\u plan\u age的代码:

    ALTER PROCEDURE get_zip_plan_age 
-- Add the parameters for the stored procedure here
@zip_code nvarchar(16),
@plan_code nvarchar(16),
@insur_age int = 0 

    AS
    BEGIN
-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

IF @insur_age > 0 
BEGIN 

    SELECT 

      [state_code], 
      [zip_code], 
      [female_value], 
      [male_value], 
      [carrier_name], 
      [update_date], 
      [insur_age], 
      [plan_code], 
      [spousal_discount] 

      FROM [state_zipcode_plans] 

      WHERE (([insur_age] = @insur_age) 
      AND ([zip_code] = @zip_code) 
      AND ([plan_code] = @plan_code)) 

      ORDER BY [male_value], [plan_code]

END  

    ELSE BEGIN

      SELECT 

      [state_code], 
      [zip_code], 
      [female_value], 
      [male_value], 
      [carrier_name], 
      [update_date], 
      [insur_age], 
      [plan_code], 
      [spousal_discount] 

      FROM [state_zipcode_plans] 

      WHERE (([zip_code] = @zip_code) 
      AND ([plan_code] = @plan_code)) 

      ORDER BY [male_value], [plan_code]

END
 END
 GO

在方法搜索_Zip _计划_年龄_按钮_单击您已多次设置cmd.CommandText和cmd.CommandType。在这种情况下,只能设置一次-它们的值为cmd.CommandText=“get_carrier_info”;cmd.CommandType=CommandType.storedProcess

<> >为了使代码更可维护,请考虑将命令创建到工厂,


就sp而言,我只能看到get\u zip\u plan\u age的sp。

我的建议是:如果要将内容绑定到用户可以查看/编辑的表单,请不要使用
SqlDataReader
。这将使数据库连接保持打开状态—可能会持续很长时间

如果您使用表单来显示数据,我会使用ORM(对象关系映射器)从数据库中获取对象列表——或者,如果这不是您想要的,那么至少使用一个
DataTable
,它获取数据,然后允许您断开与数据库的连接,直到您实际需要更新内容为止(或读取新数据)

至于调用存储的进程:

  • BIG使用
    块的
    奖励
  • 我会尽可能晚地打开连接-它不必在创建参数和内容时打开-只在需要读取数据之前打开它
  • 我会尝试将UI代码(读取文本框,绑定到网格)从实际代码中分离出来以加载数据-您可能希望在某个时候将其放入数据访问层(单独的类库)-不要将加载数据与操作UI混为一谈
  • 我会将对单个存储过程的各个调用分开——只有四个方法,您可以在需要时使用所需的参数调用它们
所以我试着用这样的方法:

protected void Search_Zip_Plan_Age_Button_Click(object sender, EventArgs e)
{       
    string _connStr = ConfigurationManager.ConnectionStrings["PriceFinderConnectionString"].ConnectionString;

    DataTable data = LoadZipPlanAge(_connStr, .......);

    Zip_Plan_Age_GridView.DataSource = data;
    Zip_Plan_Age_GridView.DataBind();
}


protected DataTable LoadZipPlanAge(string connString, Int64 insurAge, string zipCode, string planCode)
{
    string storedProcName = "dbo.get_zip_plan_age";                    
    DataTable table = new DataTable();

    using (SqlConnection cn = new SqlConnection(connString))
    using (SqlCommand cmd = new SqlCommand(storedProcName, cn))
    {
       cmd.CommandType = CommandType.StoredProcedure;

       // create parameters
       cmd.Parameters.Add("@insur_age", SqlDbType.Int64).Value = int64Value;
       .......


       SqlDataAdapter dap = new SqlDataAdapter(cmd);
       dap.Fill(table);
    }

    return table;
}
用逻辑,

  • 如果选择了保险年龄,则仅显示该年龄的最低女性费率,选择年龄为指定年龄的最高(1)最低女性值
  • 如果为保险年龄选择了“全部”,则通过选择顶部(1)最小女性值来显示最低女性费率,其中邮政编码、计划代码与指定的搜索值匹配,并且男性费率大于0,按保险年龄、男性值、承运人名称分组,并针对65、70、75、80年龄组的每个年龄组进行联合
下面是我用来获得最低女性比率的存储过程:

      ALTER PROCEDURE [dbo].[get_lowest_female_rate] 
-- Add the parameters for the stored procedure here
@zip_code nvarchar(16),
@plan_code nvarchar(16),
@insur_age int = 0 

      AS
      BEGIN

-- SET NOCOUNT ON added to prevent extra result sets from
-- interfering with SELECT statements.
SET NOCOUNT ON;

          -- Insert statements for procedure here

          -- If an Insurance Age is selected, only display the min Female rate for that age 

          IF @insur_age > 0 
          BEGIN 

    SELECT TOP(1)  
      [carrier_name], 
      [insur_age],
      MIN([female_value])

      FROM [state_zipcode_plans] 

      WHERE (([insur_age] = @insur_age) 
      AND ([zip_code] = @zip_code) 
      AND ([plan_code] = @plan_code)
      AND ([female_value] > 0)) 

      GROUP BY        
      [insur_age], [female_value], [carrier_name]

END  

        -- If ALL is selected for Insurance Age, Display Lowest Female Rate for Each of the Age Groups 65, 70, 75, 80 

        ELSE BEGIN

      SELECT TOP(1)           
      [carrier_name], 
      [insur_age],
      MIN([female_value])

      FROM [state_zipcode_plans]

      WHERE  (([zip_code] = @zip_code) 
      AND ([plan_code] = @plan_code)
      AND ([female_value] > 0)
      AND ([insur_age] = 65)) 

      GROUP BY        
      [insur_age], [female_value], [carrier_name]

        UNION 
      SELECT TOP(1)           
      [carrier_name], 
      [insur_age],
      MIN([female_value])

      FROM [state_zipcode_plans]

      WHERE  (([zip_code] = @zip_code) 
      AND ([plan_code] = @plan_code)
      AND ([female_value] > 0)
      AND ([insur_age] = 70)) 

      GROUP BY        
      [insur_age], [female_value], [carrier_name]

UNION 
      SELECT TOP(1)           
      [carrier_name], 
      [insur_age],
      MIN([female_value])

      FROM [state_zipcode_plans]

      WHERE  (([zip_code] = @zip_code) 
      AND ([plan_code] = @plan_code)
      AND ([female_value] > 0)
      AND ([insur_age] = 75)) 

      GROUP BY        
      [insur_age], [female_value], [carrier_name]

       UNION 
      SELECT TOP(1)           
      [carrier_name], 
      [insur_age],
      MIN([female_value])

      FROM [state_zipcode_plans]

      WHERE  (([zip_code] = @zip_code) 
      AND ([plan_code] = @plan_code)
      AND ([female_value] > 0)
      AND ([insur_age] = 80)) 

      GROUP BY        
      [insur_age], [female_value], [carrier_name]     

     END
   END

好的,我将创建一个单独的(SqlCommand cmd123=cn.CreateCommand())对于每个存储过程,是吗?基本上是的,但是如果您使用前面提到的命令模式,您可以隐藏此低级逻辑并以通用方式创建此Sql命令。还可以使用DataTable断开您的结果,正如其他人在下面建议的那样。您可以为此提供一些示例代码吗?目前我编写了使用(SqlCommand cmd=cn.CreateCommand())语句多次使用不同的变量请不要放置“ASP.NET C#SQL”在标题中。我们有相应的标签。感谢您的回复!我不会编辑任何数据,只会显示它。所以我应该使用ORM还是DataTable?您可以在dataTables上添加一个带有更多示例代码的链接吗?除了DataTable data=LoadZipPlanAge(_connStr,…)之外,我还放了什么;?@Brian McCarthy:如果您只想显示数据,那么数据表就可以了。SqlDataAdapter将填充您的DataTable,并从底层SQL语句在DataTable中创建必要的列-您不需要更多,只需要我显示的代码。DataTable是ADO.NET的一部分-任何ADO.NET教程都会向您展示如何使用和充分利用数据表。一些ADO.NET教程链接:,或