如何使用 VB.NET 配置 DataAdapter 以使用 Sql Server 存储过程执行 Select、Update、Insert 和 Delete 命令?

Posted

技术标签:

【中文标题】如何使用 VB.NET 配置 DataAdapter 以使用 Sql Server 存储过程执行 Select、Update、Insert 和 Delete 命令?【英文标题】:How can I use VB.NET to configure a DataAdapter to use Sql Server Stored Procedures for Select, Update, Insert and Delete commands? 【发布时间】:2014-09-24 15:42:23 【问题描述】:

我创建了一个测试项目,它只是通过使用存储过程使 DataGridView 与 Sql Server 一起工作。我负责 Employee 类中的所有 SQL Server 机制,以及窗体 frmMain 上的 datagridview 活动。

本质上,我将在所有四个命令中使用一些相同的列。

我想一次定义每个参数,然后将其添加到所有需要它的命令中。麻烦的是,我收到错误“SqlParameter 已被另一个 SqlParameterCollection 包含”。有人告诉我,对于使用它的每个命令,我必须以不同的方式命名每个参数。我可以看到这是怎么回事,但我希望那里有人知道如何使一列一参数方法起作用。

Employee Class

Imports System.ComponentModel
Imports System.Data
Imports System.Data.SqlClient

Public Class Employees
    'Declarations
    Private dtEmployees As DataTable
    Private daEmployeer As SqlDataAdapter
    Const HotmixCn As String = "Data Source=MyServer;Initial Catalog=MyDatabase;User ID=USER;Password=password"
    Private Cn As SqlConnection

    'Properties
    Public Property EmployeeList As DataTable

        Get
            Return dtEmployees
        End Get
        Set(value As DataTable)
            dtEmployees = value

        End Set
    End Property


    'Methods
    Public Sub New()
        ' Try
        Cn = New SqlConnection(HotmixCn)
        daEmployeer = New SqlDataAdapter
        Dim cmdSelectEmployees As New SqlCommand
        Dim cmdInsertEmployee As New SqlCommand
        Dim cmdUpdateEmployee As New SqlCommand
        Dim cmdDeleteEmployee As New SqlCommand
        'Configure the Select command (!! have to for SP)
        With cmdSelectEmployees
            .CommandType = CommandType.StoredProcedure
            .CommandText = "uspTestGetEmployees"
            .Connection = Cn

        End With

    --- Same thing for Insert, Update and Delete
        '
        '/// Add The Parameters To All Three Commands ///
        Dim parm As SqlParameter
        parm = New SqlParameter
        With parm
            .ParameterName = "@EmpNo"
            .SqlDbType = SqlDbType.Int
            .Direction = ParameterDirection.Input
            .SourceColumn = "EmpNo"
        End With
        cmdInsertEmployee.Parameters.Add(parm)
        cmdUpdateEmployee.Parameters.Add(parm)
        'cmdDeleteEmployee.Parameters.Add(parm)
        '
----- Similar for remaining parameters            

        '
        'Include the individual commands in the dataadapter
        daEmployeer.SelectCommand = cmdSelectEmployees
        daEmployeer.UpdateCommand = cmdUpdateEmployee
        daEmployeer.InsertCommand = cmdInsertEmployee
        daEmployeer.DeleteCommand = cmdDeleteEmployee
        '/// Fill the Datatable
        dtEmployees = New DataTable

        Cn.Open()
        daEmployeer.Fill(dtEmployees)
        Cn.Close()


        'Catch ex As Exception
        'MsgBox(ex.Message)

        'End Try

    End Sub
    'Events

End Class

这是 DataGridView 附带的小代码:

Imports DataLayer

Public Class frmMain
    Dim emp As New Employees

    Private Sub frmMain_Load(sender As Object, e As EventArgs) Handles MyBase.Load

        dgvEmployees.DataSource = emp.EmployeeList

    End Sub
End Class

【问题讨论】:

代码太多...尝试将其简化为一个非常基本的示例,以便对您的问题产生更多兴趣。 【参考方案1】:

您似乎正在尝试将相同的参数添加到两个不同 SqlCommand 中的两个不同参数集合中。从错误消息中可以看出,这是不可能的。

一种可能的解决方法是创建原始命令的副本并将此副本添加到不同的命令中。这是一项乏味的工作,所以最好创建一个 Extension Method 来为你做这些脏活

Imports System.Runtime.CompilerServices

Module SqlClientExtensions

    <Extension()> 
    Public Function Duplicate(ByVal src As SqlParameter) As SqlParameter
        Dim copy = New SqlParameter(src.ParameterName,src.SqlDbType, src.Size, src.Direction,
                                      src.IsNullable, src.Precision, src.Scale, src.SourceColumn,
                                      src.SourceVersion, src.Value)

        Return copy; 
    End Function 

End Module

现在你可以写这样的东西了

Dim parm As SqlParameter
parm = New SqlParameter
With parm
    .ParameterName = "@EmpNo"
    .SqlDbType = SqlDbType.Int
    .Direction = ParameterDirection.Input
    .SourceColumn = "EmpNo"
End With
cmdInsertEmployee.Parameters.Add(parm)
cmdUpdateEmployee.Parameters.Add(parm.Duplicate())
cmdDeleteEmployee.Parameters.Add(parm.Duplicate())

我还注意到SqlParameter 实现了接口ICloneable。所以,乍一看,你似乎可以写这样的东西

Dim b = new SqlCommand()
Dim p = new SqlParameter()
p.ParameterName = "@Test"
b.Parameters.Add(p)

Dim b1 = new SqlCommand()
Dim p1 = CType(CType(p, ICloneable),SqlParameter)
b1.Parameters.Add(p1)

但这会退回到原来的错误“SqlParameter 已经被另一个 SqlParameterCollection 包含”(而且,即使它有效,我更喜欢扩展方法以使其清晰)

【讨论】:

这看起来是一种非常优雅的方式来做我想做的事——这很重要,因为我将不得不多次做相同但不同的情况。我不完全明白将扩展名放在哪里,但我会找到的。谢谢,如果在我了解它时有人没有提出更好的方法,我会将其标记为答案。 上面关于vb.net中扩展方法的链接应该解释了很多。而且,当然,等待你喜欢的时间,这就是 SO 的工作原理 这是一种非常酷的方式来完成这项任务,这将为我和其他人省去很多麻烦。完美运行。【参考方案2】:

我想一次性定义每个参数,然后将它添加到所有需要它的命令中。

很遗憾,这是不允许的。您必须硬着头皮重新定义选择、更新和删除命令的参数。

【讨论】:

以上是关于如何使用 VB.NET 配置 DataAdapter 以使用 Sql Server 存储过程执行 Select、Update、Insert 和 Delete 命令?的主要内容,如果未能解决你的问题,请参考以下文章

VB.Net 如何将 app.config 文件移动到自定义位置

VB.net - 活动目录连接字符串

vb.net链接数据库怎么出现链接不上请大神指点?

VB.NET/ASP.NET 4.0 自定义配置部分:“创建配置部分处理程序时出错”

如何确定 VB.Net DataRow 中是不是存在列

需要 vb.net 代码来查看/编辑离线硬盘的注册表