Не знаю как назвать эту тему, ибо не знаю о чем спрашиваю
В вижуал с++ есть возможность создать функцию вида:
bool Execute(const char* QueryString, ...);
и вызывать ее так:
Execute("UPDATE auctions SET bidder = %u WHERE auctionId = %u", HighestBidder, Id);
т.е. то что в объявлении было как ... туда можно передать сколь угодно параметров HighestBidder, Id.
Я не знаю как называется такое явление.
В общем вопрос, можно ли сделать так в си шарп? Пробовал
{
}
Не катит, пишет что "Type expected" и указывает на многоточие после запятой
В общем вопрос, можно ли сделать так в си шарп? Пробовал
{
}
{
}
Правда вам придется как-то форматировать каждый элемент массива args в запрос.
Я кстати делал универсальный механизм (типобезопасный!) для выполнения хранимых процедур и запросов с параметрами.
Если заинтересует - пишите в ПМ или аську.
Зависит от того, как вы хотите работать с БД. Вообще, передача строки с подстановкой параметров запроса хреновый способ. Прямой путь к атакам типа SQL инъекций.
Есть в классе System.String функция Format. Умеет подставлять в строку значение, тоже кстати использует приведенный способ:
Это называется метод с переменным числом параметров.
Компилятор просто создает массив из передаваемых объектов, тогда как в C/C++ имеет место прелопачивание стека во время исполнения таких функций.
Кстати говоря, тип параметров можно контроллировать: object в объявлении позволит запихивать какие угодно данные (это супертип для всех типов в .NET), string - позволит передавать строки, а MyObject - только экземпляры твоих MyObject объектов.
Спасибо что указал на метод Format, я то уж подумал вручную прийдется заменять :)
На счет универсального механизма, я не совсем понимаю что это такое, какие преимущества и прочее. Просто хватать все что предлагают не считаю правильным, что сделаю сам то и сделаю :)
Механизм такой. Пример кода:
...
[StoredProcedure("sdo_membership_CreateGroup")]
public abstract GroupEntry CreateGroup(Guid? parent_id, [StringValidator(1, 256)] string group_name);
[StoredProcedure("sdo_membership_DeleteGroup")]
public abstract void DeleteGroup(Guid group_id);
[StoredProcedure("sdo_membership_GetGroups")]
public abstract ICollection<GroupEntry> GetGroups(Guid? parent_id);
...
}
Описывается абстрактный класс, в котором объявляются абстрактные методы, соответствующие хранимым процедурам или конкретным запросам. В последнем случае вместо атрибута StoredProcedureAttribute указывается SqlAttribute с текстом запроса.
Специальный кодогенератор (в рантайме) выполняет наследование этого класса и реализует все такие методы (создает DbCommand и подставляет ему параметры!). Параметры метода ставятся в соответствие параметрам запроса/хранимки. Поддерживаются, кажется, все стандартные типы данных: различной длины и знаковости целые числа, вещественные числа, строки, гуиды, также есть интеграция с Nullable<T> (в примере Guid?), что позволяет передавать в СУБД Null значения.
Всего есть три типа вызовов:
1) вызов без результата - ExecuteNonQuery (для вставки, обновления, или хранимка просто ничо не вертает),
2) вызов с возвратом единственной строки
3) вызов с возвратом набора строк (ICollection<T>)
Результаты вызовов заворачиваются в специальные классы (GroupEntry в примере), которые мы также определяем сами. Каждый класс содержит набор свойств, которые мы ставим в соответствие некоторому столбцу в результирующем наборе (также посредством атрибута).
Пару дней назад добавил поддержку кэширования вызовов, так как эта кухня активно используется в паре проектов (веб и не очень :) и кэш был просто необходим.
Вообще похожая технология вызова хранимок ипользуется сейчас в LINQ (честно! я независимо от микрософта эту хрень разработал), но там каждый раз при вызове происходит отражение по методу.
В любом случае, рекомендую попробовать LINQ - это позволит резко поднять производительность труда программиста при работе с СУБД.