【问题标题】:CommandText Property Has Not Been Initialized, retrieving dataCommandText 属性尚未初始化,正在检索数据
【发布时间】:2017-07-25 08:15:51
【问题描述】:
Private Sub ButtonSubmitID_Click(sender As Object, e As EventArgs) Handles ButtonSubmitID.Click
    Dim comm As New SqlCommand
    Dim conn As New SqlConnection
    conn.ConnectionString = "Data Source = localhost\SQLEXPRESS; Initial Catalog = test2Forms; Integrated Security = SSPI;"
    comm.Connection = conn
    Dim ID = TextBoxID.Text
    comm.Parameters.AddWithValue("@ID", ID)
    Dim adapter As SqlDataAdapter = New SqlDataAdapter(comm.CommandText, comm.Connection)
    comm.CommandText = "SELECT * FROM withActivityLog3 WHERE ID = @ID"
    Dim records As DataSet = New DataSet
    adapter.Fill(records)
    DataGridView2.DataSource = records
End Sub

CommandText 属性尚未初始化是我收到的错误。我能够在表单加载时将所有数据从数据库中提取到 GridView 中,但是当我尝试使用按钮触发器上的 WHERE 子句将其缩小到一个 ID 时,会出现上述错误。我使用调试器一次跟踪一个步骤,命令和连接字符串看起来正确。我还使用 SQL Server 命令行成功地在我的数据库上复制了查询。我正在搜索主键 (ID),因此预期结果将是数据库中唯一标识的行。

【问题讨论】:

  • 仔细查看您的代码...您设置comm.CommandText 之后将它(空)传递给DataAdapter。您不需要为 DataAdapter 创建命令对象或连接对象 - 只需传递 SQL 和连接字符串。由于您确实需要/需要参数的 DBCommand 对象,因此您不需要 DataAdapter,只需直接填充数据表......不需要本地 DataSet 枯萎。 Rubber duck debugging
  • 是的,我看不懂
  • 请注意,您现在可以在您认为有用或信息丰富的 任何 Q 或 A 旁边投票(点击向上箭头)。正如tour 解释的那样,投票可以帮助其他人找到好帖子。这是一种被动的方式,即使不发布答案,人们也可以参与并帮助他人。
  • 太棒了。谢谢!我会这样做的!
  • 这很有帮助,能够在下班前进行更改,但还不能完全测试。我的错,大声笑​​,我将表单设计为在大型显示器上全屏显示,而在家里的笔记本电脑上,我无法使用按钮。我很想看看这是否有效。这对我来说确实更有意义。我以前看过 Using 代码,这似乎是最好的方法。我将不得不记住 DRY 原则,我也喜欢橡皮鸭调试。也许我可以在工作中找人一起做。

标签: vb.net datagridview


【解决方案1】:

至于你知道的问题:

' initialize DataAdapter with (EMPTY) commandtext
Dim adapter As SqlDataAdapter = New SqlDataAdapter(comm.CommandText, comm.Connection)
' initialize Command Text
comm.CommandText = "SELECT * FROM withActivityLog3 WHERE ID = @ID"

当您将CommandText 传递给DataAdapter 时,它是空的,因为您尚未设置它会导致错误。

不过,您的代码效率相当低。重写:

' form level conn string
Private TheConnString As String = "Data Source = localhost\..."

Private Sub ButtonSubmitID_Click(sender ...

    Dim dt As New DataTable

    Using dbcon As New MySqlConnection(TheConnString)
        Using cmd As New MySqlCommand("select * from Sample where Id = @id", dbcon)

            cmd.Parameters.Add("@id", MySqlDbType.Int32).Value = Convert.ToInt32(TextBox2.Text)
            dbcon.Open()
            dt.Load(cmd.ExecuteReader)

            dgvA.DataSource = dt

        End Using
    End Using
End Sub

注意:这里使用 MySQL,但对于 Sqlite、Access、SQL Server 等的概念是相同的

  • 无需在任何使用它的地方键入或粘贴连接字符串。一个表单级变量将允许DRY (Dont Repeat Yourself) 代码。
  • 任何实现Dispose() 方法的东西都应该被丢弃。这包括几乎所有的 DB Provider 对象。 Using 语句允许您声明和初始化一个对象,并在 End Using 处处理它。未能Dispose 的事物可能会导致泄漏,甚至用尽连接或资源来创建诸如 DB Command 对象之类的事物。
  • 无需创建本地DbDataAdapter。这些是非常强大和有用的小动物,它们的作用远不止填充DataTable。如果这就是你所做的一切,你可以在DbCommand 对象上使用ExecuteReader 方法。
  • 您也不需要本地DataSet。与名称相反,这些不保存数据,而是DataTables。由于只有一个并且是本地的(方法结束时超出范围),因此您不需要 DataSet 来存储它。
  • 应该使用Add 方法而不是AddWithValue。上面的代码指定了参数的数据类型,因此编译器不需要猜测。当然,随之而来的是需要将文本转换为数字...
  • ...由于这是用户输入,您不应该信任用户,因此Integer.Tryparse 更合适:I like pie 不会转换为整数。数据验证是您开始数据库操作之前应该做的事情。
  • Dim ID = TextBoxID.Text 使用的是毫无意义的代码。您无需将文本框文本移动到新变量中即可使用它。但是,ID 可能用于存储整数值

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-10-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多