【问题标题】:Change DropDownList Based On Another DropDownList Value In Asp.Net Using Vb.Net使用 Vb.Net 根据 Asp.Net 中的另一个 DropDownList 值更改 DropDownList
【发布时间】:2021-11-11 07:46:58
【问题描述】:

我尝试根据另一个下拉列表值更改我的下拉列表值。在输出屏幕上加载了第一个下拉列表值,但在第一个下拉列表项更改后未显示第二个下拉列表值

Dim con As New SqlConnection("Data Source=DESKTOP-311HSD1;Initial Catalog=Covid;Integrated Security=True;Pooling=False")

Dim cmd As SqlCommand
Dim ds As DataSet
Dim sda As SqlDataAdapter
Dim sdr As SqlDataReader

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load
    Try
        If con.State = ConnectionState.Closed Then
            con.Open()
        End If
        If Not IsPostBack Then
            BindDistrict()
        End If
    Catch ex As Exception
    End Try
End Sub
Private Sub BindDistrict()

    Try
        Using sqlConn As New SqlConnection("Data Source=DESKTOP-311HSD1;Initial Catalog=Covid;Integrated Security=True;Pooling=False")
            Using sqlCmd As New SqlCommand()
                sqlCmd.CommandText = "SELECT DISTINCT District FROM [dbo].[Hospital]"
                sqlCmd.Connection = sqlConn
                sqlConn.Open()
                Dim da As New SqlDataAdapter(sqlCmd)
                Dim dt As New DataTable()
                da.Fill(dt)
                drp_dist.DataSource = dt
                drp_dist.DataValueField = "District"
                drp_dist.DataTextField = "District"
                drp_dist.DataBind()
                sqlConn.Close()
                drp_dist.Items.Insert(0, New ListItem("Select District", "0"))
            End Using
        End Using
    Catch ex As Exception

    End Try
End Sub
Private Sub drp_dist_SelectedIndexChanged(sender As Object, e As EventArgs) Handles drp_dist.SelectedIndexChanged

    Dim district As String = drp_dist.SelectedValue.ToString()
    BindHospital(district)

End Sub
Private Sub BindHospital(ByVal district As String)

    Dim dist As String = district
    Try
        Using sqlConn As New SqlConnection("Data Source=DESKTOP-311HSD1;Initial Catalog=Covid;Integrated Security=True;Pooling=False")

            Using sqlCmd As New SqlCommand()
                sqlCmd.CommandText = "SELECT * FROM [dbo].[Hospital] WHERE District='" + dist + "'"
                sqlCmd.Connection = sqlConn
                sqlConn.Open()
                Dim da As New SqlDataAdapter(sqlCmd)
                Dim dt As New DataTable()
                da.Fill(dt)
                drp_hospital.DataSource = dt
                drp_hospital.DataValueField = "HospitalID"
                drp_hospital.DataTextField = "Hospital_Name"
                drp_hospital.DataBind()
                sqlConn.Close()
                drp_hospital.Items.Insert(0, New ListItem("Select Hospital", "0"))
            End Using
        End Using
    Catch ex As Exception

    End Try
End Sub

【问题讨论】:

  • 为什么要共享所有不做任何事情的类级变量?但不分享drp_hospital 和drp_dist?
  • 不要写空的 Catch 块。你只是在吞下错误。
  • 不要在使用的方法之外声明连接。连接需要使用 Using blocks 来处理。
  • 不要连接字符串来构建 CommandText。始终使用参数来避免 sql 注入。

标签: asp.net vb.net


【解决方案1】:

首先,不要在页面加载时搞乱打开或关闭连接。

接下来,请记住 sqlCommand 对象有

sql command text - no need for separate variable
sql connection - no need for separate variable
sql reader - no need for separate reader

sql 数据适配器 - 除非您要更新数据“认为适应 = 需要更改数据”,否则不要使用。

因此,上述概念可以让您编写更少的代码、更简洁的代码,并让您专注于代码,而不是所有阅读器和连接的东西。

接下来,您可以(应该)考虑将连接字符串放在项目设置区域中。 (它有一个连接构建器,更好的是它还可以为您更新网络配置,而无需您付出任何努力。

好的,考虑到以上内容了吗?

Protected Sub Page_Load(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Load

    If Not IsPostBack Then

        drp_dist.DataSource = MyRst("SELECT DISTINCT District FROM [dbo].[Hospital]")
        drp_dist.DataBind()
        drp_dist.Items.Insert(0, New ListItem("Select District", "0"))
    End If

End Sub

按理说,您可能必须在 100 多个地方输入 sql 和命令。既然你一遍又一遍地这样做,那么一个非常简单的辅助例程就会有所帮助。

接下来,您在第一页加载时加载网格、组合框或其他任何内容 - 但仅加载第一页(回发 = false)。

因此,级联两个组合框的代码可以而且应该如下所示:

YES 将组合框的 DataText 和 DataValue 设置放在标记中 - 而不是在代码中。 (它的自我记录)。

好的,现在我们需要级联部分。确保标记中的第一个组合是 autopostback=true。

所以,我们现在有:

Private Sub BindHospital(ByVal district As String)

    Using sqlCmd As New SqlCommand("SELECT * FROM Hospital WHERE District = @dist",
                    New SqlConnection(My.Settings.TEST4))

    sqlCmd.Parameters.Add("@dist", SqlDbType.NVarChar).Value = district
    sqlCmd.Connection.Open()
    drp_hospital.DataSource = sqlCmd.ExecuteReader()
    drp_hospital.DataBind()
    drp_hospital.Items.Insert(0, New ListItem("Select Hospital", "0"))

End Using

using 块也会为您关闭连接 - 所以我们不必这样做。

还有那个简单的辅助例程?

这个:

Public Function MyRst(strSQL As String) As DataTable

    Dim rstData As New DataTable

    Using cmdSQL As New SqlCommand(strSQL, New SqlConnection(My.Settings.TEST4))
        cmdSQL.Connection.Open()
        rstData.Load(cmdSQL.ExecuteReader)
    End Using

    Return rstData

End Function

即使您不使用 MyRst 辅助例程?

将您的连接字符串设置 OUT 的代码。您在数百个地方使用它,更糟糕的是,在网络发布时您需要更改它。

【讨论】:

  • 连接需要它自己的变量,因为它应该在使用后被丢弃。连接、命令和阅读器,都是一次性的。如果不这样做,可能会杀死您的数据库服务器(没有可用的连接)
  • sql 命令对象是一个 using 块,因此与命令对象有关的任何事情——包括作为命令对象一部分的连接对象都将被处理掉。您最好在一个对象中执行此操作,而不是创建两个单独的对象(一个连接对象和一个命令对象)。通常我们不使用某个类,然后您应该手动处理该类的所有对象吗?真的吗?如果出于某种愚蠢的原因您创建了一个单独的新连接对象,那么是的,当然您必须将该对象处置或放置在 using 块中。
  • 我想基本的问题是,当命令对象已经有一个连接对象时,为什么还要麻烦声明和创建一个连接对象?为什么?
猜你喜欢
  • 2020-03-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-27
  • 2018-02-23
  • 1970-01-01
相关资源
最近更新 更多