SQL 服务器和 VB.NET 应用程序的 MultipleActiveResultSets

MultipleActiveResultSets for SQL Server and VB.NET application

我正在尝试使用 VB.NET 应用程序从 SQL 服务器获取多个数据集。每次我尝试执行查询的问题, 我收到此消息:

Cannot change property 'ConnectionString'. The current state of the connection is open

然后我尝试通过启用 MARS

来修复它
<connectionStrings>
    <add name="ConString" 
         providerName="System.Data.SqlClient" 
         connectionString="Data Source=my-PC;Initial Catalog=Project;Persist Security Info=True; MultipleActiveResultSets=true;User ID=user;Password=*****" />
</connectionStrings>

这是我的代码

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim obj, body
    obj = TextBox1.Text
    body = TextBox2.Text


    For Each mail In getemail()
        Send_mail(mail, obj, body, getattachment(mail))
    Next
    MsgBox("Traitement effectué")


End Sub
Function getemail() As List(Of String)

    Dim strMailTo As New List(Of String)
    Dim SQL As String = "Select EMail  FROM  [USER]  WHERE EMail Is Not NULL And MatriculeSalarie   Is Not NULL And [EMail] <> '' and EtatPaie = 3 and BulletinDematerialise = 1  "
    Dim cmd As New SqlCommand
    Dim sqLdr As SqlDataReader
    Dim dr As DataRow
    Try

        ConnServer()
        cmd.Connection = con
        cmd.CommandText = SQL
        Using sda As New SqlDataAdapter(cmd)
            Using ds As New DataTable()
                sda.Fill(ds)
                sqLdr = cmd.ExecuteReader()
                For i = 0 To ds.Rows.Count - 1
                    dr = ds.Rows(i)
                    strMailTo.Add(dr("EMail"))
                Next
            End Using
        End Using
        Return strMailTo
        sqLdr.Close()

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

    End Try
    closeCon()

    Return strMailTo
End Function

Function getattachment(email) As String()
    Dim SQL As String = "Select MatriculeSalarie  FROM [USER] WHERE [EMail]='" & email & "'"
    Dim cmd As New SqlCommand
    Dim sqLdr As SqlDataReader
    ConnServer()
    cmd.Connection = con
    cmd.CommandText = SQL
    Dim mat As String
    mat = ""
    Dim Dir As String = ConfigurationManager.AppSettings("path1").ToString
    Dim file()
    sqLdr = cmd.ExecuteReader()

    While sqLdr.Read
        mat = sqLdr.GetValue(sqLdr.GetOrdinal("MatriculeSalarie"))
    End While
    file = IO.Directory.GetFiles(Dir, mat.Substring(1) & "*.pdf")
    sqLdr.Close()
    Return file
End Function

如果您要做的只是在 Catch 中显示消息框,请不要在数据库代码中执行此操作。让错误冒泡到用户界面代码并将 Try 放在调用方法的地方。

不要声明没有数据类型的变量。带有 Option Infer 的按钮代码设置 objbody.

的类型
Private ConStr As String = "Your connection string"

Private Sub Button1_Click(sender As Object, e As EventArgs) Handles Button1.Click
    Dim obj = TextBox1.Text
    Dim body = TextBox2.Text
    Dim emails As New List(Of String)
    Try
        emails = getemail()
    Catch ex As Exception
        MessageBox.Show(ex.Message.ToString, "Error retrieving email list")
        Exit Sub
    End Try
    For Each email In emails
        Try
            Send_mail(email, obj, body, getattachment(email))
        Catch ex As Exception
            MessageBox.Show(ex.Message, "Error getting attachments")
        End Try
    Next
    MessageBox.Show("Traitement effectué")
End Sub

SubFunction 使用的参数必须有一个 DataType

我不知道你在这里做什么

While sqLdr.Read
        mat = sqLdr.GetValue(sqLdr.GetOrdinal("MatriculeSalarie"))
 End While

每次迭代都会覆盖mat的先前值。我只能假设您只需要一个值,在这种情况下,您可以使用 ExecuteScalar 来获取结果集第一行的第一列。在连接关闭之前不要对数据做任何事情。只需获取原始数据并关闭 (End Using) 连接。稍后处理数据。

总是 使用参数。数据库服务器不将参数视为 executable 代码。它们只是价值观。可以插入的 executable 代码示例是“Drop table [USER];”参数值所属的位置。糟糕!

Function getemail() As List(Of String)
    Dim SQL As String = "Select EMail  FROM  [USER]  
                            WHERE EMail Is Not NULL 
                            And MatriculeSalarie Is Not NULL 
                            And [EMail] <> '' 
                            And EtatPaie = 3 
                            And BulletinDematerialise = 1;"
    Dim dt As New DataTable
    Using con As New SqlConnection("Your connection string"),
            cmd As New SqlCommand(SQL, con)
        con.Open()
        Using reader = cmd.ExecuteReader
            dt.Load(reader)
        End Using
    End Using
    Dim strMailTo As New List(Of String)
    strMailTo = (From row As DataRow In dt.AsEnumerable
                 Select row.Field(Of String)(0)).ToList
    Return strMailTo
End Function


Function getattachment(email As String) As String()
    Dim SQL As String = "Select MatriculeSalarie  FROM [USER] WHERE [EMail]='" & email & "'"
    Dim mat As String
    Using con As New SqlConnection(ConStr),
            cmd As New SqlCommand(SQL, con)
        cmd.Parameters.Add("@email", SqlDbType.VarChar).Value = email
        con.Open()
        mat = cmd.ExecuteScalar().ToString()
    End Using
    Dim Dir As String = ConfigurationManager.AppSettings("path1").ToString
    'Your original code was fine, no need for searchPattern.
    'I added this so you could see if your search pattern was what you expected.
    Dim searchPattern = mat.Substring(1) & "*.pdf"
    Debug.Print(searchPattern) 'Appears in the Immediate window
    Dim file = IO.Directory.GetFiles(Dir, searchPattern)
    Return file
End Function