2013-06-26 3 views
0

Я пытаюсь параметризовать создание SQL с помощью OleDbCommand, чтобы избежать SQL-инъекции. Поэтому я хочу использовать общий метод, который может это сделать, и вернуть объект, который я могу использовать далее.Закройте OleDbConnection, если он передан как параметр

Я хочу использовать код на странице: http://msdn.microsoft.com/en-us/library/system.data.oledb.oledbcommand.parameters.aspx

public void CreateMyOleDbCommand(OleDbConnection connection, 
    string queryString, OleDbParameter[] parameters) 
{ 
    OleDbCommand command = new OleDbCommand(queryString, connection); 
    command.CommandText = 
     "SELECT CustomerID, CompanyName FROM Customers WHERE Country = ? AND City = ?"; 
    command.Parameters.Add(parameters); 

    for (int j=0; j<parameters.Length; j++) 
    { 
     command.Parameters.Add(parameters[j]) ; 
    } 

    string message = ""; 
    for (int i = 0; i < command.Parameters.Count; i++) 
    { 
     message += command.Parameters[i].ToString() + "\n"; 
    } 
    Console.WriteLine(message); 
} 

Вопрос 1. Он передает параметр в качестве значения. Итак, мне нужно позвонить connection.Close в конце? connection.Close не упоминается в приведенной выше ссылке, так требуется? Я не хочу, чтобы соединения с моей базой данных оставались открытыми во время выполнения кода.

Вопрос 2. Мой исходный код был:

dbReader = new OleDbCommand("select * from Table1 where Table1.Company = '" + company + "'", dbConnection).ExecuteReader(); 
dbReader.Read(); 

if (dbReader.HasRows) 
{ 
    //Do operations using dbReader["Company"] 
} 

И

new OleDbCommand("...insert sql query...", dbConnection).ExecuteNonQuery() 

Должен ли я вернуть OleDbCommand command? что я могу выполнить как command.ExecuteReader() и command..ExecuteNonQuery()

+0

Прежде всего, так как я понимаю 'queryString', который вы передаете' OleDbCommand', является командный текст, так почему вы устанавливаете это свойство после, а не вручную, а не передаете его конструктор? Соединение лучше закрывать (если необходимо) в методе, который вызывает 'CreateMyOleDbCommand'. И из-за имени метода кажется правильным вернуть 'OleDbCommand' –

+0

Ничего себе, этот код точно так же, как на сайте Microsoft. На самом деле плохой пример – Steve

+0

Кажется, что часть с установкой 'CommandText' не нужна и должна быть удалена) –

ответ

2

Пример, который вы показали, действительно плох. Я думаю, что Microsoft должен быть проинформирован об этом очень плохом коде на своем сайте.

Постараюсь сделать лучший пример и объяснить, почему

public OleDbCommand CreateMyOleDbCommand(OleDbConnection connection, 
    string queryString, OleDbParameter[] parameters) 
{ 
    OleDbCommand command = new OleDbCommand(queryString, connection); 
    command.Parameters.AddRange(parameters); 
    return command; 
} 

Во-первых, этот метод должен возвращать OleDbCommand с параметром и его CommandText инициализирован правильно. Поэтому я изменил возвращаемое значение метода от void до OleDbCommand. Таким образом, вы можете использовать команду в вызывающем коде для выполнения своих запросов.

Во-вторых, OleDbCommand имеет конструктор, который получает текст команды и соединение. Построение OleDbCommand с помощью этого конструктора позволит избежать передачи текста команды после этого, а также установить соединение с параметром.

В-третьих, чтобы добавить массив параметров в набор параметров OleDbCommand, вам необходимо использовать метод AddRange коллекции Parameters.

Теперь в вашем кодовом коде, где вы определили OleDbConnection, вы можете вызвать этот метод, откройте соединение и выполните команду (ExecuteReader, ExecuteNonQuery или ExecuteScalar в зависимости от текста команды). Конечно, когда вы открываете соединение, вы также закрываете его.