В приведенном выше примере продемонстрирована работа с
членами объектов пользовательских типов. Синтаксис достаточно прост –
оператором выбора члена объекта выступает двойное двоеточие.
Свойства
Свойства ведут себя очень похоже на переменные с
такими «странными» именами. В соответствии с наличием в декларации свойства get
и set его можно использовать в присваиваниях как справа, так и слева. Все
свойства нашего класса поддерживают и чтение, и запись.
ПРЕДУПРЕЖДЕНИЕ
Изменять состояние объекта в геттере
свойства крайне не рекомендуется! Дело в том, что SQL Server предполагает, что чтение свойства не приведет к изменению состояния. Если вы прочитаете
значение такого свойства у переменной, то новое состояние объекта доживет
ровно до окончания выполнения геттера, а затем он будет возвращен в исходное
состояние.
Методы
Все публичные методы класса будут доступны в T-SQL.
Реализация методов предоставляет значительно большую гибкость, чем реализация
свойств, но также накладывает на разработчика некоторую ответственность.
Константные методы
По умолчанию считается, что все методы являются
константными, т.е. не изменяют состояния объекта. Это позволяет использовать их
в операторах select – идеология SQL запрещает какие-либо изменения данных в
читающих запросах. Иначе бы невозможно было обеспечить необходимые свойства
изоляции транзакций. При этом так же, как и для геттеров свойств, сервер
принудительно обеспечивает константность – изменения, произведенные в «обычном»
методе будут отменены сразу после выполнения метода, даже для переменных T-SQL.
Для проверки этих рассуждений добавим в наш класс вот
такой метод:
public
SqlDouble ResetR(SqlDouble newR)
{
SqlDouble Result = R;
R = newR;
return
Result;
}
Попробуем воспользоваться «дырой» и неявно изменить
состояние объекта:
declare @p SqlPoint
set @p::x=3
set @p::y=4
select @p::R
select @p::ResetR(10)
select @p::R
Программисту на традиционных объектно-ориентированных
языках естественно ожидать получения различных результатов во втором и третьем
запросах – ведь вызов ResetR модифицирует приватное поле объекта. Увы, во всех
трех случаях вернется одно и то же значение.
Неконстантные методы
Конечно же, SQL Server позволяет объектам иметь и
неконстантные методы. Такие методы нужно помечать атрибутом SqlMethod со
свойством IsMutator, установленным в true. При этом неконстантным методам
запрещено возвращать какие-либо значения. Для иллюстрации реализуем
«правильную» версию метода ResetR в нашем классе:
[SqlMethod(IsMutator=true, OnNullCall=false)]
public void ResetR2(SqlDouble newR)
{
R = newR;
}
Подробнее об атрибуте SqlMethod
Атрибут SqlMethod (System.Data.Sql.SqlMethodAttribute)
унаследован от атрибута SqlFunction, рассмотренного ранее при описании функций.
У него есть конструктор без параметров и два новых свойства. Одно из них, IsMutator, мы уже рассмотрели. Второе – OnNullCall – пока недокументировано;
скорее всего речь идет об оптимизации выполнения запросов, при которой сервер
может игнорировать вызовы методов на NULL-объектах. Тем не менее пока что мне
не удалось добиться проявления каких-либо эффектов, связанных с этим свойством.
Сериализация
Поскольку любой сервер баз данных непрерывно
перемещает данные из памяти на диск и обратно, первостепенной задачей является
обеспечение эффективного механизма преобразования «живых» объектов в пригодный
для хранения формат и обратно. Известно, что универсального решения не
существует. Поэтому разработчики SQL Server предоставили программистам широкий
выбор возможностей по управлению этим процессом.
Основу управления сериализацией закладывают
обязательные для пользовательских типов атрибуты Serializable и
System.Data.Sql.SqlUserDefinedTypeAttribute.
У второго из них есть следующие параметры:
Format
//
using System.Data.Sql
Format
SqlUserDefinedTypeAttribute.Format {get; set}
Единственный обязательный параметр конструктора
атрибута. Он определяет выбранный формат сериализации. Может принимать
следующие значения:
Native - в этом случае MS SQL Server использует
стандартный способ преобразования объекта в бинарное представление. Не требует
от разработчика почти никаких усилий, и заявлен в документации как «самый
эффективный в большинстве случаев». Для того, чтобы можно было использовать
этот формат, все поля класса должны быть блиттируемыми. Этот специфичный для
.NET термин означает наличие общего представления для управляемой и
неуправляемой памяти. К счастью, встроенные скалярные типы, а также их массивы
и структуры, построенные из них, являются блиттируемыми. Увы, тип System.String
(как и все ссылочные типы) блиттируемым не является. Кроме ограничения по типам
полей, класс должен быть помечен атрибутом
[StructLayout(LayoutKind.Sequential)]. Для этого формата нельзя указывать
параметр SqlUserDefinedTypeAttribute.MaxByteSize.
Рекомендуем скачать другие рефераты по теме: диплом государственного образца, реферат по экологии.