Мне нужно начать с того, что в исходном посте ничего не говорится о неправильно , по сути, и вы можете продолжать использовать этот код просто отлично.
Но ... мы можемвсе еще лучше.
Нет необходимости передавать аргумент SqlCommand
в InitializeSqlCommand()
по ссылке.ИМО это ошибка в коде VB.ByVal
здесь достаточно хорош, и ByRef
предоставляет объект вашей команды вещам, которые вам могут не понадобиться.
В функции CreateSqlConnection()
я склонен полагать, что если вы создаете соединение, вы 'скоро тоже захочу открыть.Плюс, мы можем немного сократить метод.
Я также стремлюсь либо поместить строки подключения непосредственно в мои эквивалентные модули DatabaseUtil, либо собрать модуль, чтобы он мог загрузить строку из файла конфигурации.Я не хочу каждый раз передавать эти данные в метод CreateSqlConnection()
.Сложите эти два абзаца так:
Private ReadOnly Property ConnectionString As String
Get
Return "connection string here"
End Get
End Property
Public Function CreateSqlConnection() As SqlConnection
Dim result As New SqlConnection(ConnectionString)
result.Open()
Return result
End Function
Это небольшая вещь, но SqlCommand
также реализует IDisposble
, поэтому в идеале он также будет в блоке using
.На самом деле, в существующем методе InitializeSqlCommand()
нет ничего, что вы не можете выполнить напрямую с помощью конструктора SqlCommand
, так как CommandType.Text
уже используется по умолчанию.Идем дальше и импортируем пространство имен DatabaseUtil
, и вы можете соединить эти два абзаца следующим образом:
using (var sqlConnection = DatabaseUtil.CreateSqlConnection())
using (var cmd = new SqlCommand(query, sqlConnection))
{
Я также беспокоюсь о командной функции InitializeSqlCommand()
, которая принимает строку query
, но делаетнет обеспечения для параметров запроса.Да, вы все равно можете добавить параметры позже в коде, но по моему опыту это имеет тенденцию поощрять использование конкатенации строк для данных параметров ... или, точнее, не может адекватно препятствовать этому, что равносильно тому же.Вы хотите убедиться, что в приложении нет уязвимостей SQL-инъекций.Если вы продолжаете использовать InitializeSqlCommand()
, я структурирую его так:
Public Function InitializeSqlCommand(cn As SqlConnection, query As String, ParamArray paramters() As SqlParamter) As SqlCommand
Dim result As SqlCommand = cn.CreateCommand()
result.CommandText = query
If parameters IsNot Nothing AndAlso parameter.Length > 0 Then
result.Parameters.AddRange(parameters)
End If
Return result
End Sub
Нет необходимости вызывать sqlConnection.Close()
, если соединение было создано в блоке using
.То же относится и к DataReader.
Наконец, типичный шаблон для DataReader - , а не для проверки свойства HasRows
.Обычно достаточно только проверить результаты метода Read()
и, как правило, в цикле while
.
Собрать все вместе, включая пересмотренные функции VB, например:
var parameters = new SqlParameter[] { }; //define parameters here
using (var sqlConnection = DatabaseUtil.CreateSqlConnection())
using (var cmd = DatabaseUtil.InitializeSqlCommand(sqlConnection, query, parameters))
using (var reader = cmd.ExecuteReader())
{
while(reader.Read())
{
//some code here
}
}