在aspx页面上用C#从Gridview中用按钮更新SQL Server表

本文关键字:按钮 更新 SQL Server Gridview aspx | 更新日期: 2023-09-27 17:59:19

UPDATE:根据katstevens的解释更新代码。

我有一个用非固定人数更新的表,用于跟踪出勤情况。当用户点击一个带有天气或他们是否到达的按钮时,我需要更新表格,换句话说,当用户到达时,他们找到自己的名字,然后点击一个应该触发代码的按钮,只更新他们的信息。

我认为Gridview将是理想的选择,因为它可以适应不同数量的与会者。我发现findcontrol方法不能正常工作,因为我的update语句在itemtemplate字段中找不到标签。有没有其他方法可以做到这一点,这样后面的代码就可以找到控制,并且无论有多少人,视图都可以显示所有与会者?

此特定代码返回此错误:CS0103:名称"FIRST_name"在当前上下文中不存在

这是(许多)最新的尝试,以防它可以修复。

代码隐藏:已注释掉

这里是sqldatasourcecontrol:

<asp:SqlDataSource ID="SqlDataSource1" runat="server" ConnectionString="<%$ ConnectionStrings:myconnection %>"
    UpdateCommand="UPDATE mytable SET CHECK_IN = 1 where mytable.[ID] = @lbl_ID"
    SelectCommand="select command stuff...
    <SelectParameters>
        <asp:ControlParameter ControlID="more select stuff..." PropertyName="SelectedValue" />
    </SelectParameters>
    <UpdateParameters>
        <asp:Parameter Name="LBL_ID" />
    </UpdateParameters>
</asp:SqlDataSource>                

这是按钮:

                <asp:TemplateField ShowHeader="False">
                    <ItemTemplate>
                        <asp:Button ID="btntkchkin" runat="server" CausesValidation="false" CommandName="Update"
                            Text="Check In" OnClick="btntkchkin_Click" />
                    </ItemTemplate>
                </asp:TemplateField>

在aspx页面上用C#从Gridview中用按钮更新SQL Server表

首先让我澄清一下你的问题的几点:

许多数据绑定控件都将处理任意数量的数据行(您的"与会者数量")-它们将一直重复,直到绑定所有数据。它们在布局和表示(网格、列表、带/不带分页等)方面有所不同,但它们的基本原理是,它们将显示与它们绑定的行数或行数。其中包括GridView(仅限表格显示)、ListViewepeater

在代码隐藏中运行的查询存在一些问题。首先解析要使用的四个变量,然后创建命令。在查询中不提供任何参数,但注入了2个字符串(FIRST_NAME和LAST_NAME)。然后将这四个变量绑定到不包含任何参数的parameters集合。

重构代码,带说明

string CommandText = "UPDATE [mytable] SET CHECK_IN = 1 where mytable.[FIRST_NAME] = @FirstName and[mytable].[LAST_NAME] = @LastName";

@开头的两个占位符(@FirstName@LastName)是参数,是添加到Parameters集合中的值的占位符。

using (SqlConnection conn = new SqlConnection(ConfigurationManager.ConnectionStrings["myconnection"].ConnectionString))
using (SqlCommand cmd = new SqlCommand(CommandText, conn))
{

最好使用块包装连接和命令,以便在完成时正确处理它们。将它们放在另一个之上只意味着相同的{ }集合适用于两者。

    string FIRST_NAME = ((Label)(GridView1.FindControl("lbl_FIRST_NAME")));
    string LAST_NAME = ((Label)(GridView1.FindControl("lbl_LAST_NAME")));
    string SESSION_ID = ((Label)(GridView1.FindControl("lbl_SESSION_ID")));
    string ID = ((Label)(GridView1.FindControl("lbl_ID"))).Text;

您实际上并不需要这些变量,它们也不会直接在GridView中找到(见下文),但我已经将它们留在了中,以备您需要。

我们不需要将Connection绑定到Command,因为我们之前在using()块中已经这样做了。

    cmd.Parameters.AddWithValue("@FirstName", FIRST_NAME);
    cmd.Parameters.AddWithValue("@LastName", LAST_NAME);

cmd.Parameters.Add在较新版本的.NET中已弃用,取而代之的是.AddWithValue,它允许您同时指定参数名称和值。

我们不需要绑定@SSN_ID@ID,因为它们没有在查询中指定。如果要将它们添加到中,则需要修改命令的UPDATE语句以包含这些值。如果要使用它们,请按照与上面相同的方式绑定它们。

    conn.Open();
    cmd.ExecuteNonQuery();

最后,我们打开连接,然后执行查询。无需关闭任何东西;他们会自动处置。

    GridView1.DataBind();
}

然后我们重新绑定数据源以检索更新的值。

在GridView中查找控件

不幸的是,当GridView渲染时,它会添加额外的容器来将数据保存在表中。仔细想想,在GridView上运行.FindControl()是行不通的,因为您查找的控件将存在于GridView的每一行。

为了解决你的问题,而不是让事情变得更加困难,我会做以下事情:

在数据源中添加一个UpdateCommand,用相关数据(当前时间、签入标志等)更新相关行:

UpdateCommand="UPDATE [mytable] SET CHECK_IN = 1 where mytable.[FIRST_NAME] = @First_Name AND [mytable].[LAST_NAME] = @Last_Name"

将这两个参数添加到UpdateParameters部分,以便在运行查询时绑定这些值。

<UpdateParameters>
    <asp:Parameter Name="First_name" />
    <asp:Parameter Name="Last_name" />
</UpdateParameters>

然后将按钮的CommandName设置为Update,以便在该行上触发更新事件。

<asp:Button ID="btntkchkin" runat="server" CausesValidation="false" CommandName="Update" Text="Check In" OnClick="btntkchkin_Click"/>

最后,在GridView上,设置DataKeyNames="FIRST_NAME, LAST_NAME",以便DataSource知道将这些值绑定到查询中。

从本质上讲,每当单击btntkchkin按钮时,它都会回发到服务器,并通过填写按钮所在行的任何参数来运行UpdateCommand。这将在服务器上执行,页面将在浏览器中重新加载。我相信它也会为您在数据源上调用DataBind——如果没有,您总是可以添加一个事件处理程序来显式地执行此操作。

奖金建议

就我个人而言,我会使用"唯一ID"字段来更新签入时间,而不是匹配名字和姓氏——如果你有两个同名的人,会发生什么?

您可以将附加字段(SSN_ID,ID)添加到UPDATE命令中,方法是将它们与参数占位符(@SSN_ID,@ID)一起添加,然后将asp:Parameter添加到UpdateParameters部分。如果标签设置为Bind(),则在运行命令时,DataSource将自动将它们绑定到所有查询字段。

如果这些都不起作用或不能解决你的问题,请留下评论。