- •Организация c#-системы ввода-вывода: байтовые и символьные потоки. Встроенные потоки.
- •Классы потоков. Класс Stream. Классы байтовых потоков. Классы символьных потоков. Классы двоичных потоков.
- •1.5. Классы символьных потоков:
- •1.6. Классы двоичных потоков:
- •Класс FileStream и файловый ввод-вывод на побайтовой основе. Открытие и закрытие файла. Запись данных в файл. Считывание байтов из объекта класса FileStream.
- •Файловый ввод-вывод с ориентацией на символы. Использование класса StreamWriter. Использование класса StreamReader.
- •Считывание и запись двоичных данных. Класс BinaryWriter. Класс BinaryReader.
- •Наиболее важные методы выходного потока BinaryWriter:
- •Навигация по файловой системе: классы для работы с файловой системой.
- •Получение сведений о файле; копирование файлов; перечисление файлов в папке; изменение расширения файлов.
- •5.3. Изменение расширения файлов
- •Основы организации потоков. Потоки и многозадачность.
- •Пространство имен System.Threading. Класс Thread. Создание потока.
- •Создание потока. Чтобы создать поток, необходимо создать объект типа Thread. В классе Thread определен следующий конструктор: public Thread(ThreadStart entryPoint),
- •Приоритет потоков. Класс Thead поддерживает установку и получение приоритета потока. Для этого используется перечисление ThreadPriority. Его значения:
- •Использование нескольких потоков. Планирование потоков, приоритеты потоков. Можно создавать в программе несколько дочерних потоков.
- •Создать статический метод SimpleWork() в классе MultiThread (перед методом Main), который выводит на экран Id-номер каждого потока:
- •Проблемы одновременности и синхронизации потоков. Общий доступ к данным из разных потоков, предотвращение коллизий.
- •Синхронизация доступа к общим данным с помощью блокировок.
- •2) Выполнить блокировку операторов в ранее используемых методах SimpleWork и run:
- •Управление временем существования потоков.
- •Краткий обзор ado.Net. Три стороны технологии ado.Net. Пространство имен System.Data.
- •2.2 Три стороны технологии ado.Net
- •15.Поставщики данных ado.Net. Поведение объектов подключения.
- •Объектная модель ado.Net.
- •Создание соединения с источником данных. Члены типа dbConnection. Обработка исключений при работе с ms sql
- •Конструкторы
- •Свойства
- •События
- •Конструкторы
- •Свойства
- •Выборка, добавление, удаление и обновление данных с помощью sql-запросов на подсоединенном уровне.
- •Вывод информации с использованием объекта чтения данных: создание SqlDataReader; чтение данных из DataReader; чтение полей из текущей записи; закрытие DataReader.
- •Сравнение DataReader и DataSet:
- •Чтение данных из DataReader:
- •Организация хранения данных. Объект DataSet.
- •Строки: объект DataRow.
- •Конструкторы:
- •Свойства
- •Передача данных между источником данных и объектом DataSet. Обновление базы данных с помощью адаптера данных.
Строки: объект DataRow.
Содержимое таблицы (непосредственно данные) задается набором DataRows – это конкретное множество строк таблицы, каждая из которых является объектом-представителем класса DataRow. Его методы и свойства представлены в таблице.
Свойства |
|
||
HasErrors |
Возвращает значение, показывающее, есть ли ошибки в строке |
|
|
Item |
Перегружен. Возвращает или задает данные, сохраненные в указанном столбце. В языке C# это свойство является индексатором класса DataRow |
|
|
ItemArray |
Возвращает или задает все значения для этой строки с помощью массива |
|
|
RowError |
Возвращает или задает пользовательское описание ошибки для строки |
|
|
RowState |
Возвращает текущее состояние строки по отношению к DataRowCollection |
|
|
Table |
Возвращает объект DataTable, содержащий данную строку |
|
|
Методы |
|||
AcceptChanges |
Сохраняет все изменения, сделанные с этой строкой со времени последнего вызова AcceptChanges |
||
BeginEdit |
Начинает операцию редактирования объекта DataRow |
||
CancelEdit |
Отменяет текущее редактирование строки |
||
ClearErrors |
Удаляет ошибки в строке, включая RowError и ошибки, установленные SetColumnError |
||
Delete |
Удаляет DataRow |
||
EndEdit |
Прекращает редактирование строки |
||
Equals(унаследовано отObject) |
Перегружен. Определяет, равны ли два экземпляра Object |
||
GetChildRows |
Перегружен. Возвращает дочерние строки DataRow |
||
GetColumnError |
Перегружен. Возвращает описание ошибки для столбца |
||
GetColumnsInError |
Возвращает массив столбцов, имеющих ошибки |
||
GetHashCode(унаследовано от Object) |
Служит хэш-функцией для конкретного типа, пригоден для использования в алгоритмах хэширования и в структурах данных, например в хэш-таблице |
||
GetParentRow |
Перегружен. Возвращает родительскую строку DataRow |
||
GetParentRows |
Перегружен. Возвращает родительские строки DataRow |
||
GetType(унаследовано от Object) |
Возвращает Type текущего экземпляра |
||
HasVersion |
Возвращает значение, показывающее, существует ли указанная версия |
||
IsNull |
Перегружен. Возвращает значение, показывающее, содержит ли нулевое значение указанный столбец |
||
RejectChanges |
Отменяет все значения, выполненные со строкой после последнего вызова AcceptChanges |
||
SetColumnError |
Перегружен. Устанавливает описание ошибки для столбца |
||
SetParentRow |
Перегружен. Устанавливает родительскую строку DataRow |
||
ToString(унаследовано от Object) |
Возвращает объект типа String, который представляет текущий Object |
||
Защищенные методы |
|
Finalize(унаследовано от Object) |
Переопределен. Позволяет объекту Object попытаться освободить ресурсы и выполнить другие завершающие операции перед тем как объект Object будет уничтожен в процессе сборки мусора. В языках C# и C++ для функций финализации используется синтаксис деструктора |
MemberwiseClone(унаследовано от Object) |
Создает неполную копию текущего объекта Object |
SetNull |
Устанавливает значение указанного DataColumn на нулевое |
Элементы набора DataRows являются объектами класса DataRow. В этом классе обеспечивается несколько вариантов реализации свойства Item, которые обеспечивают навигацию по множеству записей объекта DataTable и сохранение текущих изменений данных, сделанных за текущий сеанс редактирования базы. Посредством набора Rows реализуется возможность ссылки на любую запись таблицы. К любой записи можно обратиться напрямую, и поэтому не нужны методы позиционирования и перемещения по записям таблицы. По множеству строк позиционирование проводится по целочисленному значению индекса. Выбор записи в строке производится по строковому значению, которое соответствует имени столбца.
Работа с типом DataRow отличается от работы с DataColumn, так как у него нет общедоступного конструктора:
DataRow r=new DataRow(); // Ошибка!
Однако новый DataRow можно получить из конкретного DataTable. Допустим, нужно вставить две строки в таблицу Turistes. Метод DataTable.NewRow() добавляет строку в таблицу, а затем нужно с помощью индексатора типа добавить в каждый столбец данные:
Console.WriteLine("Добавление строк в таблицу Turistes:");
DataRow r = Turistes.NewRow();
Console.WriteLine("Состояние строки " + r.RowState);
r["Код туриста"] = 0;
r["Фамилия"] = "Nareyko";
r["Имя"] = "Nina";
r["Отчество"] = "Nikolaewna";
Turistes.Rows.Add(r);
r = Turistes.NewRow();
r["Код туриста"] = 1;
r["Фамилия"] = "Zenko";
r["Имя"] = "Sergej";
r["Отчество"] = "Iwanowich";
Turistes.Rows.Add(r);
Индексатор класса DataRow позволяет получить доступ к объекту DataColumn как по числовому индексу столбца, так и по его имени.
Связи между таблицами: объект DataRelation.
Вся мощь автономного уровня проявляется тогда, когда объект DataSet содержит несколько взаимосвязанных объектов DataTable. Между таблицами могут быть связи. Они представлены объектом DataRelation. В коллекцию данного DataSet можно вставить любое количество объектов DataRelation, которые описывают все взаимосвязи таблиц. Эти объекты позволяют клиентскому уровню выполнять навигацию между данными таблицам без обращения к сети.
Наконец, в таблицах есть первичные и вторичные ключи – объект Constraint со своими двумя подклассами UniqueConstraint и ForeighKeyConstraint описывают их. Отметим, что объекты программы и соответствующие объекты базы данных не эквивалентны.
В классе DataSet определяется свойство Relations – набор объектов – представителей класса DataRelations. Каждый такой объект определяет связи между составляющими объект DataSet объектами DataTable (таблицами). Если в DataSet более одного набора DataTable, набор DataRelations будет содержать несколько объектов типа DataRelation. Каждый объект определяет связи между таблицами DataTable. Таким образом, в объекте DataSet реализуется полный набор элементов для управления данными, включая сами таблицы, ограничения и отношения между таблицами.
(Работу со связанными таблицами БД BDTur_firma см. Лабораторная работа5_3.doc!!!)
DataRelation dr1 = new DataRelation("Turisti", ds.Tables["Туристы"].Columns["[Код туриста]"], ds.Tables["Информация о туристах"].Columns["[Код туриста]"]);
ds.Relations.Add(dr1);
DataRelation dr2 = new DataRelation("Putewki", ds.Tables["Информация о туристах"].Columns["[Код туриста]"], ds.Tables["Путевки"].Columns["[Код туриста]"]);
ds.Relations.Add(dr2);
DataRelation dr3 = new DataRelation("Oplati", ds.Tables["Путевки"].Columns["[Код путевки]"], ds.Tables["Оплаты"].Columns["[Код путевки]"]);
ds.Relations.Add(dr3);
DataRelation dr4 = new DataRelation("Sezoni", ds.Tables["Сезоны"].Columns["[Код сезона]"], ds.Tables["Путевки"].Columns["[Код сезона]"]);
ds.Relations.Add(dr4);
DataRelation dr5 = new DataRelation("Turi", ds.Tables["Туры"].Columns["[Код тура]"], ds.Tables["Сезоны"].Columns["[Код тура]"]);
ds.Relations.Add(dr5);
В загруженных таблицах не формируются автоматически все нужные объекты, в некоторых случаях необходимо сделать это самостоятельно. Сами объекты имеют также довольно тонкую и сложную структуру, поэтому это было бы довольно грубым приближением. Однако, на первых порах, для понимания сути полезно помнить следующие соотношения:
DataSet = <одна или несколько таблиц> = <один или несколько объектов DataTable>.
DataTable = <таблица>.
DataTable = <таблица> = <множество полей, столбцов, колонок> =
= <множество объектов DataColumn>.
DataTable = <таблица> = <множество строк> = <множество объектов DataRow>.
DataColumn = <столбец, поле, колонка>.
DataRow = <строка>.
DataRelation = <связь между таблицами>.
Возникает вопрос: для чего нужны эти объекты, если можно обходится и без них для вывода содержимого таблицы, например в элемент DataGridView? Дело в том, что для простого отображения информации создавать эти объекты не требуется, но в этом случае все данные будут однородными текстовыми переменными, подобно таблицам в документе Microsoft Word. DataSet не может сам сформировать структуру данных – тип переменных, первичные и вторичные ключи, связи между таблицами. Для управления такой структурой, для ее адекватного отображения (например, вывод информации с привязкой к элементам, создаваемым в режиме работы приложения) и нужно определение этих объектов.
Создание подключения к базе данных. Управляемые провайдеры.
Управляемые провайдеры. Скорее всего, одним из первых вопросов у каждого, кто начал разбираться с ADO.NET, будет: «А как создать DataSet?» Ответ будет звучать так: при помощи управляемого провайдера (managed provider). Управляемый провайдер — это набор классов, реализующих интерфейсы, определенные в пространстве имен System.Data. Речь идет об интерфейсах IDbCommand, IDbDataAdapter, IDbConnection и IDataReader:
В состав ADO.NET включены два управляемых провайдера: провайдер SQL и провайдер OleDb. Провайдер SQL специально оптимизирован под взаимодействие с Microsoft SQL Server версии 7.0 и последующих. Для других источников данных предлагается использовать провайдер OleDb, который можно использовать для обращения к любым хранилищам данных, поддерживающим протокол OLE DB. Можно сказать что, управляемый провайдер — это шлюз к хранилищу данных (например, на сервере баз данных) , при помощи которого можно произвести загрузку данных из этого внешнего хранилища в объект DataSet.
Управляемый провайдер SQL предлагает прямой доступ к хранилищам данных, при котором производительность будет максимальной. Рассмотрим особенности работы с управляемым провайдером SQL. Он предназначен только для работы с базами данных на сервере MS SQL Server и хорошо оптимизирован именно для такой работы. Типы, которые составляют управляемый провайдер SQL, определены в пространстве имен System. Data.SqlClient.
Список основных типов управляемого провайдера SQL:
SqlCommand – Представляет запрос SQL, производимый к источнику данных SQL Server.
SqIConnection – Представляет открытое соединение с источником данных.
SqIDataAdapter – Представляет соединение с базой данных и набор команд, используемыхдля заполнения объекта DataSet, а также обновления исходной базы данных после внесения изменений в DataSet.
SqIDataReader – Обеспечивает метод считывания потока данных из источника в одном направлении (вперед).
SqlError, SqlErrors, SqlException: SqlErrors представляет набор ошибок и предупреждений, возвращаемых источником данных. Сами эти ошибки и предупреждения представлены объектами SqlError. При возникновении ошибки может быть сгенерировано исключение, представленное объектом SqlException.
SqlParameter-Collection, SqIParameter – Используются для передачи значений параметров хранимой процедуре из источника данных. Параметры представлены объектами SclParameter.
При использовании управляемого провайдера SQL очень удобно использовать классы, которые предназначены для представления «родных» типов данных SQL Server 7.0 и SQL Server 2000. Эти классы определены в пространстве имен System. Data. SqlTypes. Например, SqINumeric – decimal, SqIDouble – float, Sqllnt32 – int и т.д.
Создание подключения к базе данных. Первое, что необходимо сделать — открыть соединение с базой данных:
public static void Main()
// Шаг 1: Создаем соединение
SqlConnection сn = newSq1Connection("server=(local);uid=sa;pwd-;database= Имя_БД"};
При работе с управляемым провайдером SQL не указывается значение для Provider (поскольку мы всегда подключаемся к SQL Server), кроме того, в целом используется набор пар имя — значение.
После того как соединение с использованием строки подключения установлено, мы уже действуем следующим путем: создаем объект SqIDataAdapter и определяем для него текст запроса SQL через конструктор.
Объект DataAdapter. Класс SqlDataAdapter.
DataAdapter – это своеобразный шлюз между автономными и подключенными аспектами ADO.NET. Он устанавливает подключение, и если подключение уже установлено, содержит достаточно информации, чтобы воспринимать данные автономных объектов и взаимодействовать с базой данных.
Объект адаптера данных конкретного поставщика данных автоматически обслуживает подключение к базе данных. Для повышения масштабируемости адаптеры данных держат подключение открытым минимально возможное время. Как только вызывающий процесс получит объект DataSet, вызывающий слой полностью отключается от базы данных и остается с локальной копией удаленных данных. Теперь в нем можно вставлять, удалять или изменять строки различных объектов DataTable, но физическая база данных не обновляется, пока вызывающий процесс явно не передаст объект DataSet адаптеру данных для обновления. По сути, объекты DataSet имитируют постоянное подключение клиентов, хотя на самом деле они работают с находящейся в памяти базой данных.
Хотя объект DataSet предоставляет инструмент для хранения данных в памяти, нам нужен другой инструмент для создания и инициализации различных таблиц. Это инструмент – объект DataAdapter. Он представляет собой консоль, который скрывает детали работы. Объект DataAdapter позволяет искать и сохранять данные между объектом DataSet и хранить источник данных. Объект DataAdapter также отвечает за передачу любого обновления, вставки или удаления в физической базе данных. Вы можете использовать четыре команды объекта, чтобы получить любые обновления: UpdateCommand, InsertCommand, DeleteCommand и SelectCommand.
Объект DataAdapter существует в двух формах: объекты SqlDataAdapter и OleDbDataAdapter объекты. Источник данных – это SQL Server для объектов SqlDataAdapter, любые другие OLE DB Provider – для объектов OleDbDataAdapter.
После создания DataSet и его заполнения данными мы можем программными средствами производить запросы к нему и передвигаться по таблицам. Мы можем добавлять, удалять и изменять данные, накладывать фильтры и т.д.. DataSet представляет собой отображение используемой базы данных, перенесенное на машину пользователя. При этом нет необходимости постоянно подключаться к серверу базы данных для модификации данных. Лишь иногда вы соединяете DataSet с его родительской базой данных и модифицируете ее внесенными вами изменениями.
Класс SqlDataAdapter. Для взаимодействия с базой данных после того как соединение установлено используется класс SqlDataAdapter. Он предоставляет набор выполняемых над данными команд и подключения базы данных, которые используются для заполнения объекта DataSet и обновления базы данных SQL Server. Этот класс не наследуется. Класс SqlDataAdapter содержит следующие члены:
