- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание - Эндрю Троелсен
Шрифт:
Интервал:
Закладка:
// Заполнение DataSet новыми DataTable.
DataSet myDS = new DataSet("Cars");
SqlDataAdapter dAdapt = new SqlDataAdapter("Select * From Inventory".cnStr);
dAdapt.Fill(myDS, "Inventory");
// Отображение содержимого.
PrintDataSet(myDS);
}
Обратите внимание на то, что адаптер данных создается с указанием SQL-оператора Select. Это значение будет использоваться для внутреннего построения объекта команды, которую затем можно будет получить, выбрав свойство SelectCommand. Далее, заметьте, что метод Fill() получает экземпляр типа DataSet и необязательное строковое имя, которое будет использоваться при установке свойства TableName нового объекта DataTablе (если вы не укажете имя таблицы, адаптер данных использует для таблицы имя Table).
Замечание. Метод Fill() возвращает целое число, соответствующее числу строк, затронутых SQL-запросом.
Как и следует ожидать, при передаче DataSet методу PrintDataSet() (реализованному в этой главе ранее) будет получен список всех строк таблицы Inventory базы данных Cars (рис. 22.18).
Отображение имен базы данных в понятные имена
Вы, скорее всего, знаете, что администраторы баз данных склонны создавать имена, таблиц и столбцов, которые нельзя назвать понятными для конечных пользователей. Но хорошей вестью является то, что объекты адаптера данных поддерживают внутреннюю строго типизованную коллекцию (DatаTableМаррing-Collection) типов System.Data.Common.DataTableMapping, доступную с помощью свойства TableMappings.
Рис. 22.18. Заполнение DataSet с помощью объекта адаптера данных
При желании вы можете использовать эту коллекцию для того, чтобы информировать DataTable о "дисплейных именах", которые должны использоваться при выводе содержимого. Предположим, например, что вы хотите отобразить имя Inventory, используемое для таблицы в рамках СУБД, в дисплейное имя Ассортимент. Кроме того, предположим, что вы хотите отобразить имя столбца CarID в виде Номер, а имя столбца PetName – в виде Название. Для этого в объект адаптера данных перед вызовом метода Fill() добавьте следующий программный код (и не забудьте указать using для пространства имен System.Data.Common).
static void Main(string[] args) {
…
// Отображение имен столбцов БД в имена, понятные пользователю.
DataTableMapping custMap = dAdapt.TableMappings.Add("Inventory", "Ассортимент");
custMap.ColumnMappings.Add("CarID", "Номер");
custMap.ColumnMappings.Add("PetName", "Название");
dAdapt.Fill(myDS, "Inventory");
…
}
Теперь, выполнив программу, вы обнаружите, что метод PrintDataSet() отображает "понятные" имена объектов DataTable и DataRow, а не имена, заданные структурой базы данных.
Исходный код. Проект FillDataSetWithSqIDataAdapter размещен в подкаталоге, соответствующем главе 22.
Обновление базы данных с помощью объекта адаптера данных
Адаптеры данных могут не только заполнять для вас таблицы объекта DataSet. Они могут также поддерживать набор объектов основных SQL-команд, используя их для возвращения модифицированных данных обратно в хранилище данных. При вызове метода Update() адаптера данных проверяется свойство RowState для каждой строки в DataTable и используются соответствующие SQL-команды, присвоенные свойствам DeleteCommand, InsertCommand и UpdateCommand, чтобы записать изменения данного DataTable в источник данных.
Чтобы проиллюстрировать процесс использования адаптера данных для возвращения изменении DataTable в хранилище данных, в следующем примере мы переработаем приложение CarsInventoryUpdater, созданное в этой главе ранее, чтобы на этот раз использовать DataSet и объект адаптера данных. Поскольку значительная часть приложения останется той же, сконцентрируем свое внимание на изменениях, которые необходимо сделать в методах DeleteCar(). UpdateCarPetName() и InsertNewCar() (чтобы уточнить детали, проверьте текст загружаемого программного кода для данного примера).
Первым основным изменением, которое требуется внести в приложение, является определение двух новых статических членов-переменных класса Program для представления DataSet и объекта соединения. Также, чтобы заполнить DataSet начальными данными, модифицируется метод Main().
class Program {
// Объект DataSet, доступный на уровне приложения.
public static DataSet dsСarInventory = new DataSet("CarsDatabase");
// Объект соединения, доступный на уровне приложения.
public static SqlConnection cnObj = new SqlConnection("uid-sa;pwd=;Initial Catalog=Cars;Data Source= (local)");
static void Main(string[] args) {
// Создание адаптера данных и заполнение DataSet.
SqlDataAdapter dAdapter = new SqlDataAdapter("Select * From Inventory", chObj);
dAdapter.Fill(dsCarInventory, "Inventory");
ShowInstructions();
// Программный код получения команды пользователя…
}
…
}
Обратите внимание и на то, что методы ListInventory(), DeleteCar(), UpdateCarPetName() и InsertNewCar() также были изменены с тем, чтобы они могли принять SqlDataAdapter в качестве параметра.
Установка свойства InsertCommand
При использовании адаптера данных для обновления DataSet первой задачей оказывается назначение свойствам UpdateCommand, DeleteCommand и InsertCommand действительных объектов команд (пока вы этого не сделаете, эти свойства возвращают null). Слово "действительные" для объектов команд здесь используется потому, что набор объектов команд, которые вы "подключаете" к адаптеру данных, изменяется в зависимости от таблицы, данные которой вы пытаетесь обновить. В этом примере соответствующей таблицей является таблица Inventory. И вот как выглядит измененный метод InsertNewCar().
private static void InsertNewCar(SqlDataAdapter dAdapter) {
// Сбор информации о новой машине.
…
// Формирование SQL-оператора Insert и подключение к DataAdapter.
string sql = string.Format("Insert Into Inventory" +
"(CarID, Make, Color, PetName) Values" +
"('{0}', '{1}', '{2}', '{3}')",
newCarID, newCarMake, newCarColor, newCarPetName);
dAdapter.InsertCommand = new SqlCommand(sql);
dAdapter.InsertCommand.Connection = cnObj;
// Обновление таблицы Inventory с учетом новой строки.
DataRow newCar = dsCarInventory.Tables["Inventory"].NewRow();
newCar["CarID"] = newCarID;
newCar["Make"] = newCarMake;
newCar["Color"] = newCarColor;
newCar["PetName"] = newCarPetName;
dsCarInventory.Tables["Inventory"].Rows.Add(newCar);
dAdapter.Update(dsCarInventory.Tables["Inventory"]);
}
После создания объекта команды он "подключается" к адаптеру с помощью свойства InsertCommand. Затем в DataTable таблицы Inventory добавляется новая строка, представленная объектом dsCarInventory. После добавления DataRow в DataTable адаптер выполнит SQL-команду, обнаруженную в свойстве InsertCommand, поскольку значением RowState этой новой строки является DataRowState.Added.
Установка свойства UpdateCommand
Модификации метода UpdateCarPetName() оказываются приблизительно такими же. Просто создайте новый объект команды и укажите его для свойства UpdateCommand.
private static void UpdateCarPetName(SqlDataAdapter dAdapter) {
// Сбор информации об изменяемой машине.
…
// Форматирование SQL-оператора Update и подключение к DataAdapter.
string sql = string.Format("Update Inventory Set PetName = '{0}' Where CarID = '{1}'", newPetName, carToUpdate);
SqlCommand cmd = new SqlCommand(sql, cnObj);
dAdapter.UpdateCommand = cmd;
DataRow[] carRowToUpdate = dsCarInventory.Tables["Inventory"].Select(string.Format("CarID = '{0}'", carToUpdata));
carRowToUpdate[0]["PetName"] = newPetName;
dAdapter.Update(daCarInventory.Tables["Inventory"]);
}
В данном случае, когда вы выбираете строку (с помощью метода Select()), для RowState указанной строки автоматически устанавливается значение DataRowState.Modified. Другим заслуживающим внимания моментом здесь является то, что метод Select() возвращает массив объектов DataRow, поэтому вы должны указать, какую именно строку требуется изменить.
Установка свойства DeleteCommand
Наконец, вы имеете следующую модификацию метода DeleteCar().
private static void DeleteCar(SqlDataAdaper dAdapter) {
// Получение номера удаляемой машины.
…
string sql = String.Format("Delete from Inventory where CarID = '{0}'"; carToDelete);
SqlCommand cmd = new SqlCommand(sql, cnObj);
dAdapter.DeleteCommand = cmd;
DataRow[] carRowToDelete = dsCarInventory.Tables["Inventory"].Select(string.Format("CarID = '{0}'", carToDelete));
carRowToDelete[0].Delete();
dAdapter.Update(dsCarInventory.Tables["Inventory"]);
}
В этом случае вы находите строку, которую нужно удалить (снова с помощью метода Select()), а затем устанавливаете для свойства RowState значение DataRowState.Deleted с помощью вызова Delete().
Исходный код. Проект CarslnventoryUpdaterDS размещен в подкаталоге, соответствующем главе 22.
Генерирование SQL-команд с помощью типов построителя команд
Вы должны согласиться с тем, что для работы с адаптерами данных может потребоваться ввод довольно большого объема программного кода, а также создание всех четырех объектов команд и соответствующей строки соединения (или DbConnection-объекта). Чтобы упростить дело, в .NET 2.0 каждый из поставщиков данных ADO.NET предлагает тип построителя команд. Используя этот тип, вы можете автоматически получать объекты команд, содержащие правильные типы команд Insert, Delete и Update на базе исходного оператора Select.