1

我已經創建了一個測試項目,簡單地通過使用存儲過程使DataGridView與Sql Server一起工作。我關注Employee類中的所有SQL Server機制,以及frmMain表單上的datagridview活動。如何使用VB.NET將DataAdapter配置爲使用Sql Server存儲過程進行選擇,更新,插入和刪除命令?

本質上,我將在所有四個命令中使用一些相同的列。

我想定義每個參數一次,然後將其添加到所有需要它的命令。問題是,我收到錯誤「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

代碼太多......嘗試將其剝離爲一個非常基本的示例,以獲得對您的問題更多的興趣。 – Tanner 2014-09-24 15:46:43

回答

2

看來你正試圖相同的參數添加到兩個不同的參數集合在兩個不同的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載」(並且,即使它的工作,我會喜歡的擴展方法的清晰)

+0

這看起來像一個非常優雅的方式來做我想做的事情 - 這很重要,因爲我必須多次做同樣但不同的情況。我不完全明白把擴展名放在哪裏,但我會發現。謝謝,如果在我瞭解它的時候有人沒有提出更好的方法,我會將其標記爲答案。 – MrBill 2014-09-24 16:25:18

+0

上面關於vb.net中的擴展方法的鏈接應該解釋很多。而且,當然,請等待所有你喜歡的時間,這就是如此工作 – Steve 2014-09-24 17:32:22

+1

這是一個非常酷的方式來完成這項任務,這將爲我和其他人節省很多頭痛。完美的作品。 – MrBill 2014-09-27 20:51:42

0

我想每個參數的一個時間定義,然後將其添加到需要它的所有命令。

不幸的是,這是不允許的。您必須咬住項目符號並重新定義選擇,更新和刪除命令的參數。

相關問題