Как факторизовать звонки на ado.net с параметрами? - PullRequest
0 голосов
/ 01 октября 2019

Я хочу учесть все вызовы ado.net, присутствующие в моем веб-приложении, чтобы не повторять снова и снова строку подключения и методы открытия / закрытия. Мне удалось сделать это для вызовов без параметров, но мне нужна помощь для вызовов с параметрами.

Например, у меня было:

Dim strConnexion As String = "myConnectionString"
Dim strRequete As String = "DELETE FROM tbl_devis WHERE id_devis = " + TBDevis.Text
Dim oConnection As New SqlConnection(strConnexion)
Dim oCommand As New SqlCommand(strRequete, oConnection)
oConnection.Open()
oConnection.ExecuteNonQuery()
oConnection.Close()

Я разложил его на:

ExecuteRequest("DELETE FROM tbl_devis WHERE id_devis = " + TBDevis.Text)

И код ExecuteRequest:

Public Shared Sub ExecuteRequest(ByVal strRequest As String)
    Dim strConnection As String = ChaineDeConnexion()
    Using objConnection = New SqlConnection(strConnection)
        Dim objCommand As SqlCommand
        objCommand = New SqlCommand(strRequest, objConnection)
        objCommand.Connection.Open()
        objCommand.ExecuteNonQuery()
    End Using
End Sub

Но я бы хотел иметь возможность передать в запрос Execute набор параметров. Это очень простой пример того, какой код я хочу разложить на части:

Dim strConnexion As String = "myConnectionString"
Dim strRequete As String = "DELETE FROM tbl_devis WHERE id_devis = @id_devis"
Dim oConnection As New SqlConnection(strConnexion)
Dim oCommand As New SqlCommand(strRequete, oConnection)
With (myCommand.Parameters)
    .Add(New SqlParameter("@id_devis", SqlDbType.Int))
End With
With myCommand
    .Parameters("@id_devis").Value = TBDevis.Text
End With
oConnection.Open()
oConnection.ExecuteNonQuery()
oConnection.Close()

Я думал о редактировании моей функции ExecuteRequest, чтобы добавить необязательную коллекцию параметров:

Public Shared Sub ExecuteRequest(ByVal strRequest As String, Optional ByRef sqlParameters As SqlParameterCollection = Nothing)
    Dim strConnection As String = ChaineDeConnexion()
    Using objConnection = New SqlConnection(strConnection)
        Dim objCommand As SqlCommand
        objCommand = New SqlCommand(strRequest, objConnection)
        objCommand.Parameters = sqlParameters   'objCommand.Parameters is readonly property
        objCommand.Connection.Open()
        objCommand.ExecuteNonQuery()
    End Using
End Sub

НоVS скажите мне, что objCommand.Parameters - свойство только для чтения ...

Я вижу два решения:

  • Передача массива, содержащего имя параметра, значение и тип, и прохождение черезмассив
  • Создание строкового запроса со всеми параметрами, подобными этому: "УДАЛИТЬ ОТ tbl_devis WHERE id_devis =" + TBDevis.Text ... но когда есть 30 параметров, это грязное решение, я думаю?

Какое из них было бы более чистым и надежным, пожалуйста?

Спасибо за помощь!

1 Ответ

2 голосов
/ 01 октября 2019

ParamArray - это то, что вы ищете.

Обновите свой запрос ExecuteRequest следующим образом:

Public Sub ExecuteRequest(ByVal strRequest As String, ParamArray Params() As SqlParameter)
    Dim strConnexion As String = "myConnectionString"
    Using Conn As New SqlConnection(strConnexion), Cmd As New SqlCommand(strRequest, Conn)
        Cmd.Parameters.AddRange(Params)
        Conn.Open()
        Cmd.ExecuteNonQuery()
    End Using
End Sub

, а затем вы можете назвать его как

ExecuteRequest("DELETE FROM tbl_devis WHERE id_devis = @id_devis", New SqlParameter("@id_devis", CInt(TBDevis.Text)))

Iтакже предлагает создать функцию sqlPar (имя как строка, значение как объект) с несколькими дополнительными перегрузками, чтобы упростить вызов

ExecuteRequest("DELETE FROM tbl_devis WHERE id_devis = @id_devis", sqlPar("@id_devis",  TBDevis.Text))

ParamArray позволяет добавлять неопределенное количество аргументов, например

ExecuteRequest("SELECT ID FROM Table WHERE ID IN (@A, @B, @C, @D)", sqlPar("@A", 1), sqlPar("@B", 2), sqlPar("@C", 3), sqlPar("@D", 4))

Вы должны ВСЕГДА использовать SqlParameter вместо конкатенации строк для предотвращения SQL-инъекций.

Вы должны ВСЕГДА использовать также использование для IDisposable ресурсов.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...