OleDb, где как ошибка оператора

Я пытаюсь выполнить поиск в базе данных oledb, используя идентификатор (целое число) или имя (строка) через приложение формы Windows. Пользователь выбирает тип поиска с помощью поля со списком, поскольку возможные типы поиска отличаются. Я использую переключатель для создания двух разных запросов:

        string Combo = this.comboBox1.SelectedItem.ToString();
        string text = this.textBox1.Text;
        connection.Open();
        OleDbCommand command = null;
        switch (Combo)
        {
            case "Nombre":
                command = new OleDbCommand("SELECT Id, Nombre  FROM ARTICULOS WHERE ? LIKE ? OR ? LIKE ?", connection);
                command.Parameters.AddWithValue("?", Combo);
                command.Parameters.AddWithValue("?", "%" + LowercaseFirst(text) + "%");
                command.Parameters.AddWithValue("?", Combo);
                command.Parameters.AddWithValue("?", "%"+UppercaseFirst(text)+"%");
                break;
            case "Id":
                command = new OleDbCommand("SELECT Id, Nombre  FROM ARTICULOS WHERE ? LIKE ?", connection);
                command.Parameters.AddWithValue("?", Combo);
                command.Parameters.AddWithValue("?", Convert.ToInt32(text));
                //command.Parameters.AddWithValue("?", "%" + Convert.ToInt32(text) + "%");
                break;
        }
        try
        {
            OleDbDataReader reader = command.ExecuteReader();
            while (reader.Read())
            {
                string list = "";
                list += reader.GetValue(0).ToString() + "\t";
                list += reader.GetValue(1).ToString();
                this.listBox1.Items.Add(list);
            }
        }
        catch (Exception ex)
        {
            DialogResult result = MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK);
            this.Close();
        }
        connection.Close();

Поле со списком начинается по умолчанию с Nombre (имя на испанском языке), оно показывает все элементы в базе данных (как я и хотел).

Первая проблема возникает, когда пользователь вставляет текст в текстовое поле. Например, когда я вставляю «p» в текстовое поле, оно должно отображать все, что содержит «p» (прописные и строчные буквы) внутри базы данных, чего нет.

Вторая проблема заключается в том, что когда пользователь выбирает в поле со списком Id, это приводит к ошибке Input String has not a correct format (используя инструкции с комментариями и без комментариев).

Любая идея, как изменить код для чтения элементов, которые я хочу найти в базе данных?


ИЗМЕНИТЬ

Спасибо за аппорт. Увидев ответы, я постараюсь на них ответить (слишком много информации, чтобы поместить ее в виде комментария). Сначала я изменил код, как говорит Джон, теперь он работает правильно, когда выбрано Nombre:

        this.listBox1.Items.Clear();
        string Combo = this.comboBox1.SelectedItem.ToString();
        string text = this.textBox1.Text;
        connection.Open();
        OleDbCommand command = null;
        switch (Combo)
        {
            case "Nombre":
                command = new OleDbCommand("SELECT Id, Nombre  FROM ARTICULOS WHERE Nombre LIKE ? OR Nombre LIKE ?", connection);
                command.Parameters.AddWithValue("?", "%" + LowercaseFirst(text) + "%");
                command.Parameters.AddWithValue("?", "%" + UppercaseFirst(text) + "%");
                break;
            case "Id":
                command = new OleDbCommand("SELECT Id, Nombre  FROM ARTICULOS WHERE ID LIKE ?", connection);
                command.Parameters.AddWithValue("?", "%" + Convert.ToInt32(text) + "%");
                break;
        }
        try
        {
            OleDbDataReader reader = command.ExecuteReader();
            while (reader.Read())
            {
                string list = "";
                list += reader.GetValue(0).ToString() + "\t";
                list += reader.GetValue(1).ToString();
                this.listBox1.Items.Add(list);
            }
        }
        catch (Exception ex)
        {
            DialogResult result = MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK);
            this.Close();
        }
        connection.Close();

Часть для Id все еще не работает таким образом.

Второе: *"Если ID является числовым полем, выберите ... WHERE ID не должен использовать LIKE". Я думаю, что это необходимо. Мне не нужно искать число, мне нужно искать число, подобное вставленному. Например, если пользователь выбирает Id и вставляет 1, результат не должен быть только 1, это может быть 11, 111, 231 и т. д. любое число, содержащее 1 (как это происходит с Nombre).

Наконец: необходимы функции верхнего и нижнего регистра. Я тестировал код с ними и без них, результат более полный с этими функциями. Вот код:

static string LowercaseFirst(string s)
        {
            // Check for empty string.
            if (string.IsNullOrEmpty(s))
            {
                return string.Empty;
            }
            // Return char and concat substring.
            return char.ToLower(s[0]) + s.Substring(1);
}
static string UppercaseFirst(string s)
{
            // Check for empty string.
            if (string.IsNullOrEmpty(s))
            {
                return string.Empty;
            }
            // Return char and concat substring.
            return char.ToUpper(s[0]) + s.Substring(1);
}

person Restro Fad    schedule 14.11.2014    source источник
comment
В какой именно строке? Какова ценность text и какова ваша CurrentCulture?   -  person Soner Gönül    schedule 14.11.2014
comment
Если ID является числовым полем, выберите ... WHERE ID не должен использовать LIKE.   -  person Steve    schedule 14.11.2014
comment
Restro Fad вопрос, когда вы отлаживаете этот код, предполагая, что вы прошли через код, каково значение Combo, это фактический текст, возможно, вы могли бы изменить код, чтобы он был таким, чтобы убедиться, что он правильно читает выбранное значение string Como = this.comboBox1.GetItemText(this.comboBox1.SelectedItem);   -  person MethodMan    schedule 14.11.2014
comment
@Стив,@ДжонСкит,@DJKRAZE. Я ответил в том же посте, что и edit. А также комбо получает настоящую строку, попадая внутрь нужного корпуса.   -  person Restro Fad    schedule 14.11.2014


Ответы (1)


Проблема (или по крайней мере одна проблема) заключается в том, что вы пытаетесь использовать параметр для имени столбца. Вы не можете этого сделать — параметризовать можно только значения. Имена столбцов и таблиц должны быть частью самого SQL.

Так, например, это:

case "Nombre":
    command = new OleDbCommand("SELECT Id, Nombre  FROM ARTICULOS WHERE ? LIKE ? OR ? LIKE ?", connection);
    command.Parameters.AddWithValue("?", Combo);
    command.Parameters.AddWithValue("?", "%" + LowercaseFirst(text) + "%");
    command.Parameters.AddWithValue("?", Combo);
    command.Parameters.AddWithValue("?", "%"+UppercaseFirst(text)+"%");

должно быть:

case "Nombre":
    command = new OleDbCommand(
        "SELECT Id, Nombre  FROM ARTICULOS WHERE Nombre LIKE ? OR Nombre LIKE ?", 
        connection);
    command.Parameters.AddWithValue("?", "%" + LowercaseFirst(text) + "%");
    command.Parameters.AddWithValue("?", "%"+UppercaseFirst(text)+"%");
person Jon Skeet    schedule 14.11.2014
comment
Было бы интересно узнать, что два метода Нижний/Верхний делают с входным текстом, потому что LIKE не должен заботиться о регистре. - person Steve; 14.11.2014
comment
@Steve: Да, это определенно странно, но я подозреваю, что проблема не в этом. - person Jon Skeet; 14.11.2014