4. Привязка объектов контроля к источникам данных

Интерфейс IBindingList: расширенная поддержка привязки

он определяет средства для контроля

Интерфейс IBindingList Является важнейшим интерфейсом в плане поддержки развитой привязки данных. Он определяет средства для контроля над изменениями в списке, сортировки и поиска в списке, а также обеспечивает выдачу уведомлений об изменениях, когда содержимое списка меняется. В .NET 2.0 вы можете легко создать частичную реализацию IBindingList при помощи обобщенного класса коллекции BindingList<T>. Как уже упоминалось, реализация IList Является единственным барьером, который нужно преодолеть, чтобы обеспечить привязку элементов управления Windows Forms. Однако простая реализация этого интерфейса недостаточна для поддержки той развитой привязки данных, к которой привыкли разработчики, имея дело с коллекциями вроде DataView. Важнейшим интерфейсом для поддержки привязки с модификациями коллекции данных является IBindingList. Такие модификации осуществляются либо через сам привязанный элемент управления, либо производятся «за кулисами» путем программных изменений в коллекции. Интерфейс IBindingList Позволяет также коллекции указать, поддерживает ли она сортировку или поиск, и предусматривает методы, которые будут приводить эти процессы в движение. IBindingList Является производным от IList, Поэтому при реализации IBindingList Вам нужно будет реализовать все элементы интерфейсов IList, ICollection И LEnumerable. Лучше всего сделать это путем использования либо наследования обобщенного класса BindingList<T>. В главе 9 разрабатывается законченный пример, показывающий, как это делается, с добавлением реализаций для IBindingListView, ITypedList И I Raise ItemChangingEvents. Если вам нужна более подробная информация о потреблении интерфейса IBindingList И о том, какие функции обеспечиваются каждым из его элементов, читайте дальше.

Разрешение конкуренции данных

основная проблема конкуренции данных состоит

Проблемы конкуренции данных проявляют себя в различных ситуациях, чаще всего в распределенных многопользовательских системах. Основная проблема конкуренции данных состоит в том, что при работе с отключенными данными, что по большей части и делается через ADO. NET, одни и те же данные могут редактироваться одновременно двумя различными пользователями или двумя различными частями кода. Когда сделанные изменения будут фиксироваться в хранилище данных, вам придется решать, чьи данные сохранять и что делать с конфликтами. Как описывается в приложении Г, когда в ADO. NET происходит ошибка конкуренции, на уровне доступа к данным выбрасывается исключение DBConcurrencyException. В больших промышленных системах эти ошибки часто перехватываются на рабочем уровне или под ним, и обрабатываются некоторым автоматическим образом, с возбуждением, возможно, како — го-то другого типа ошибки для уровня представления, чтобы оповестить пользователя. В меньших системах вы можете позволить исключению DBConcurrencyException Пройти наверх вплоть до уровня представления, чтобы там его обработать. Возможно также, что вы решите в ответ на ошибку конкуренции возбуждать на рабочем уровне специальное исключение. Какой бы подход вы ни избрали, для разрешения этих ошибок или представления их пользователю не существует никаких «встроенных» функциональных средств. Подготовленность пользователей в различных прикладных областях очень сильно варьируется, и соответственно варьируется степень сложности решений, которые вы можете оставить на их усмотрение, и это не дает возможности найти такие решения общего назначения, которые подошли бы всякому. Если ваши пользователи знают довольно много, вы могли бы в случае ошибок конкуренции предоставлять им UI, который позволяет сделать выбор между значениями, которые он посылают, и текущими значениями в базе данных, как показано на рис. 10.7. В случае менее подготовленных пользователей вы могли бы просто отвергать посланные ими данные и заставлять их ввести все заново. Тут вы должны продумать вопрос, как часто это может происходить и какое воздействие будет оказывать на пользователей, хотя иногда требование проделать лишнюю работу, заново вводя данные, будет меньше сбивать с толку и будет связано для них с меньшим стрессом, чем попытки понять, чего от них хочет более сложный интерфейс.

Класс SqlParameter

он отвечает за управление трансляцией

Класс SqlParameter Инкапсулирует передачу параметров сохраняемым процедурам и параметризованным запросам. Он отвечает за управление трансляцией параметров между двумя различными системами типов: системой типов. NET и системой типов базы данных. Система типов. NET содержит такие примитивы, как Int32, Float, Double, DateTime И String, А также все остальные классы. NET Framework и любые специальные классы и структуры, которые вы пишете. Эта система типов сохраняет значения в наборе данных, поскольку набор данных является просто еще одним типом в мире. NET, который способен содержать другие типы. NET посредством объектных ссылок. SQL Server имеет свою собственную концепцию системы типов, и именно эта система типов используется для сохранения данных в базе данных. Итак, класс SqlParameter Берет на себя заботу об инкапсуляции значений в системе типов. NET и передаче их базе данных в форме, которая совместима с действующей там системой типов. Вы конструируете каждый объект SqlParameter, Специфицируя имя параметра запроса, который он будет представлять, тип базы данных для параметра запроса и размер этого параметра, если в базе данных это тип переменной длины. Имеются различные перегрузки конструктора SqlParameter, Которые позволяют вам опустить спецификацию размера, и вы, кроме того, всегда можете установить эту информацию через свойства. Параметр имени, передаваемый конструктору, должен в точности соответствовать имени параметра запроса, включая символ @ в параметрах SQL. Это является специфическим для управляемого провайдера SQL Server. Если вы используете управляемый провайдер OLE DB, то там соответствующим классом будет OleDbParameter. Однако параметры OLE DB всегда передаются по их позиции в операторе, так что имя параметра игнорируется.

Преобразования типов и обработчики формата

классы typeconverter b b определяются

Для каждого встроенного типа.NET Определены функции преобразования, либо через класс, производный от TypeConverter, Либо через неявные преобразования данных в механизме привязки Windows Forms. Классы TypeConverter Определяются и ассоциируются с определенными типами, при этом они предназначены для преобразования из ассоциированного типа в один или несколько других типов. Например, класс ImageConverter Ассоциирован с типом Image, И он может выполнять преобразование в битовый массив и наоборот. Если для требуемого преобразования не существует TypeConverter, Используются возможности неявного преобразования типов Windows Forms, которые поддерживают наиболее употребительные типы.NET. Кроме того, процесс преобразования типов может корректировать значения, полученные от Обработчика формата , т. е. объекта, реализующего интерфейс IFormatProvider. Например, класс DateTimeCon — Verter Ассоциируется с типом DateTime, И может выполнять преобразования значений даты-времени из строки или в строку. Результат процесса преобразования типа String Может быть модифицирован обработчиком формата. Обработчиком формата для типа DateTime Является по умолчанию DateTimeFormatinf О, И вы можете легко задать ему, какие именно части значения даты-времени необходимо извлечь и вернуть в результирующей строке.

Содержание преобразованной строки задается путем спецификации строки формата, состоящей из маркеров, идентифицирующих части значений даты и времени. Имеются предопределенные строки формата, доступные для локализации, такие, как "D", Которая означает, что возвращаемая строка должна содержать дату в коротком формате. Обработчик формата также поддерживает специализированные строки формата, которые можно использовать для передачи маркеров обработчику формата. Дату в таком же формате можно вернуть при помощи строки формата "Mm/Dd/Yyyy", Но такие строки не будут автоматически адаптированы к локальным стандартам, как это происходит с предопределенными строками формата.

Методы GetXXX

методы принимают индекс столбца или

Методы GetXXX, Извлекающие значение столбца, определены для каждого из встроенных типов. NET. Методы принимают индекс столбца, или ординал, для позиции извлекаемого столбца, и пытаются извлечь значение столбца как указанный тип, производя при необходимости любые преобразования. Например, если вы вызываете метод GetString Для столбца, который в действительности содержит целое, для возвращаемого значения будет вызван ToString, Чтобы получить строку. Если вы попытаетесь использовать метод Getxxx, запрашивающий тип, несовместимый с действительным содержанием столбца, будет выброшено исключение. Чтобы определить позицию столбца, этот код использует метод считывателя данных GetOrdinal, Отыскивающий позицию столбца по его имени. Считыватель данных экспонирует интерфейс, аналогичный другим классам считывателей в. NET Framework. Считыватель действует подобно указателю в коллекцию элементов. Указатель исходно позиционирован непосредственно перед первым элементом. Чтобы переместить указатель на следующий элемент, вы вызываете метод Read Считывателя. Если элементов для чтения больше нет, метод Read Возвратит False. Когда указатель позиционирован на элементе, вы можете обращаться к содержимому этого элемента через те методы доступа и свойства, которые экспонирует специфический тип считывателя. В случае SqlDataReader Элементами являются строки, а к содержимому строк вы можете обращаться через индексатор, свойство Item Или методы GetXXX, Где XXX Обозначает тип столбца, который вы запрашиваете. Следующий код показывает использование индексаторов и метода Индексатор считывателя данных возвращает ссылку на object, поэтому вам нужно будет приводить значение к ожидаемому типу столбца, который вы извлекаете. Индексатор перегружен таким образом, что вы можете передавать ему либо целый индекс в строке, представляющий позицию столбца в возвращаемых строках, либо имя столбца, как показано здесь. Использование имен столбцов гораздо проще для чтения и сопровождения, хотя и чуть-чуть менее эффективно при извлечении.