Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 18.07.2011, 03:56   #1
Mixim
Форумчанин
 
Регистрация: 29.10.2009
Сообщений: 259
Вопрос Метод с переменным количеством аргументов

Разрабатываю на языке C# клиентское приложение для SQL-базы данных, состоящей из двух таблиц. Для добавления данных в таблицы использую хранимые процедуры, которые вызываю с помощью класса OleDbCommand. Этот синтаксис для первой таблицы выглядит следующим образом:
Код:
OleDbCommand command = new OleDbCommand("NameOfStoredProcedure1", currentOleDbConnection);
                command.CommandType = CommandType.StoredProcedure;
                command.Parameters.AddRange(new OleDbParameter[] {
                    new OleDbParameter("@Parameters1", OleDbType.Char),
                    new OleDbParameter("@Parameters2", OleDbType.VarChar),
                    new OleDbParameter("@Parameters3", OleDbType.Char)});
                command.Parameters[0].Value = "что-то";
                    command.Parameters[1].Value = "зачем-то";
                    command.Parameters[2].Value = "почему-то";
                currentOleDbConnection.Open();
                command.ExecuteScalar();
                currentOleDbConnection.Close();
                    command.Dispose();
Для второй таблицы:
Код:
OleDbCommand command = new OleDbCommand("NameOfStoredProcedure2", currentOleDbConnection);
                command.CommandType = CommandType.StoredProcedure;
                command.Parameters.AddRange(new OleDbParameter[] {
                    new OleDbParameter("@Parameters1", OleDbType.VarChar),
                    new OleDbParameter("@Parameters2", OleDbType.VarChar),
                    new OleDbParameter("@Parameters3", OleDbType.VarChar),
                    new OleDbParameter("@Parameters4", OleDbType.Single)});
                command.Parameters[0].Value = "какие-то данные1";
                    command.Parameters[1].Value = "какие-то данные2";
                    command.Parameters[2].Value = "какие-то данные3";
                    command.Parameters[3].Value = 2.2;
                currentOleDbConnection.Open();
                command.ExecuteScalar();
                currentOleDbConnection.Close();
                    command.Dispose();
Как видно, вышеописанный код очень похож, и поэтому решил создать отдельно общий метод с переменным количеством аргументов с использованием ключевого слова params, т.е. написать что-то вроде:
Код:
void AddData(OleDbConnection acurrentOleDbConnection, String aNameOfStoredProcedure, params String ParametersName, params OleDbType atype, params object adata){...}
но компилятор указывает, что params в аргументах может указываться только один раз, т.е. данная методика не подходит. Конечно можно создать отдельно некоторый класс, полями которого будут ParametersName, atype, adata, но как-то не хочется так делать.
Может кто подскажет каким образом можно решить указанную проблему?
Из всех классических книг, посвященных программированию, ненавижу всего одну - русский перевод книги Роберта Седжвика-"Фундаментальные алгоритмы C++". Предпочитаю читать её в оригинале.
Mixim вне форума Ответить с цитированием
Старый 18.07.2011, 07:21   #2
Spawn™Production®
Форумчанин
 
Аватар для Spawn™Production®
 
Регистрация: 06.05.2011
Сообщений: 287
По умолчанию

Только если params object, а дальше приводить. Класс предпочтительнее создать.
Spawn™Production® вне форума Ответить с цитированием
Старый 18.07.2011, 08:51   #3
Carbon
JAVA BEAN
Участник клуба
 
Аватар для Carbon
 
Регистрация: 22.04.2007
Сообщений: 1,329
По умолчанию

Можно создать метод с параметрами по умолчанию, а там уже использовать их как именованные.
Carbon вне форума Ответить с цитированием
Старый 19.07.2011, 04:28   #4
Mixim
Форумчанин
 
Регистрация: 29.10.2009
Сообщений: 259
Сообщение

Порылся вчера немного на MSDN и понял, что имена параметров можно не указывать, главное, чтобы они вставлялись в той же последовательности, в которой они идут в хранимой процедуре. В итоге получил следующий вполне работоспособный код:
Код:
public void CallStoredProcedure(OleDbConnection aConnection, String aStoredProcedureName, params String[] aValues) //передаем OleDb-соединение, имя хранимой процедуры, аргумент с модификатором params отвечает за необходимые аргументы уже самой хранимой процедуры
                {
                    OleDbCommand command = new OleDbCommand(aStoredProcedureName, aConnection);  //создаем объект типа OleDbCommand, в конструкторе которого указываем имя хранимой процедуры и OleDb-соединение
                        command.CommandType = CommandType.StoredProcedure;//указываем, что тип команды - "хранимая процедура"
                    try
                    {
                        for (Int32 i = 0; i < aValues.Length; i++)
                        {
                            command.Parameters.AddWithValue("", aValues[i]);  //заполняем параметры команды переданными аргументами
                        }
                        aConnection.Open();  //открываем соединение
                            command.ExecuteScalar();                        //выполняем команду как скалярное выражение
                    }
                    finally  //при любом раскладе(получили исключительную ситуацию или все прошло отлично) выполняем следующие строки
                    {
                        aConnection.Close();  //разумеется закрываем открытое ранее соединение
                        command.Parameters.Clear();  //освобождаем память от динамически созданных ранее параметров
                            command.Dispose();  //освобождаем память от созданной динамической переменной
                    }
                }
Если кому-то будет интересно, начеркал специально давольно-таки подробные комментарии к коду.
Благодаря синтаксису вышеописанного метода, мы можем без особых хитростей вызвать его с любым количеством аргументов. Например:
Код:
CallStoredProcedure(myOleDbConnection, "AddAnything", "1", "2", "3");
//или
CallStoredProcedure(myOleDbConnection, "EditMyData", "aaa", "bbb", "ccc", "ddd", "eee")
Если же в качестве аргумента для выполнения хранимой процедуры необходимо передать значение числового типа(Int32, UInt16, Single и т.д.), то пишем примерно следующее:
Код:
Single price=5.5, quantity=12;//допустим эту переменную надо передать
CallStoredProcedure(myOleDbConnection, "AddGoods", "NameOfGoods", price.ToString(), quantity.ToString());//т.е. приводим наши числа к строке, а за последующий перевод из строки в число отвечает SQLServer - создали немного лишней работы, но зато сделали обобщение
Из всех классических книг, посвященных программированию, ненавижу всего одну - русский перевод книги Роберта Седжвика-"Фундаментальные алгоритмы C++". Предпочитаю читать её в оригинале.

Последний раз редактировалось Mixim; 19.07.2011 в 04:39. Причина: Дополнение
Mixim вне форума Ответить с цитированием
Старый 19.07.2011, 11:27   #5
veniside
Старожил
 
Регистрация: 03.01.2011
Сообщений: 2,508
По умолчанию

> т.е. приводим наши числа к строке

логичнее тогда было бы, наверно, сделать aValues типа object, а не String, чтобы можно было передавать произвольные типы. Правда, справится ли AddWithValue() с произвольным объектом — это вопрос.
"Когда приходит положенное время, человек перестаёт играть в пинбол. Только и всего."
veniside вне форума Ответить с цитированием
Старый 19.07.2011, 14:17   #6
Mixim
Форумчанин
 
Регистрация: 29.10.2009
Сообщений: 259
Подмигивание

Цитата:
Сообщение от veniside Посмотреть сообщение
логичнее тогда было бы, наверно, сделать aValues типа object, а не String, чтобы можно было передавать произвольные типы. Правда, справится ли AddWithValue() с произвольным объектом — это вопрос.
Спасибо за совет, он помог решить напрямую, а не "обходными путями" одну небольшую проблему при вызове моего метода и кроме того, использование типа Object действительно является более рациональным решением, чем String . Метод AddWithValue() вроди бы при использовании типа Object и при передаче непосредственно в качестве аргументов типов String и Double отлично все "переваривает".
Из всех классических книг, посвященных программированию, ненавижу всего одну - русский перевод книги Роберта Седжвика-"Фундаментальные алгоритмы C++". Предпочитаю читать её в оригинале.

Последний раз редактировалось Mixim; 19.07.2011 в 14:20.
Mixim вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц



Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Ф-я с переменным количеством параметров.. Lucky777 Помощь студентам 19 02.06.2011 23:54
Функции с произвольным количеством и типом аргументов. Crudelis Общие вопросы C/C++ 1 16.06.2010 00:10
Простейшая задача на функцию со сменным количеством аргументов iFireFly Общие вопросы C/C++ 1 07.01.2010 12:21
Циклы с переменным количеством шагов Froost Общие вопросы Delphi 1 10.11.2009 19:30
Нужна помощь в решении задачек, тема "Циклы с переменным количеством шагов" DJ Kost Помощь студентам 3 16.01.2009 13:26