СДЕЛАЙТЕ СВОИ УРОКИ ЕЩЁ ЭФФЕКТИВНЕЕ, А ЖИЗНЬ СВОБОДНЕЕ

Благодаря готовым учебным материалам для работы в классе и дистанционно

Скидки до 50 % на комплекты
только до

Готовые ключевые этапы урока всегда будут у вас под рукой

Организационный момент

Проверка знаний

Объяснение материала

Закрепление изученного

Итоги урока

Взаимодействие с базой данных

Категория: Информатика

Нажмите, чтобы узнать подробности

Просмотр содержимого документа
«Взаимодействие с базой данных»

Взаимодействие с базой данных

Взаимодействие с базой данных

  Создание базы данных  Как правило, для хранения больших наборов данных используются различные базы данных. В WPF, как и в целом в .NET, мы можем работать с различными системами управления баз данных - MS SQL Server, Oracle, MySQL, MongoDB, Postgres и т.д. В данном случае рассмотрим взаимодействие приложения на WPF и базы данных MS SQL Server. Хотя общие принципы работы с другими БД не будут теми же.

Создание базы данных

  • Как правило, для хранения больших наборов данных используются различные базы данных. В WPF, как и в целом в .NET, мы можем работать с различными системами управления баз данных - MS SQL Server, Oracle, MySQL, MongoDB, Postgres и т.д. В данном случае рассмотрим взаимодействие приложения на WPF и базы данных MS SQL Server. Хотя общие принципы работы с другими БД не будут теми же.
 Прежде всего для работы с базами данных должен быть установлен и запущен MS SQL Server. Все необходимые файлы для загрузки можно найти на офсайте по ссылке MS SQL Server 2014 Express
  • Прежде всего для работы с базами данных должен быть установлен и запущен MS SQL Server. Все необходимые файлы для загрузки можно найти на офсайте по ссылке MS SQL Server 2014 Express
 Итак, создадим новый проект. Пусть он будет называться DbApp. Вначале создадим базу данных, к которой мы будем подключаться. Для этого откроем специальную программу SQL Server 2014 Management Studio, которая устанавливается вместе с MS SQL Server и которая служит для управления базами данных. В левом древовидном меню найдем пункт Databases, нажмем на него правой кнопкой мыши и в появившемся контекстном меню выберем пункт New Database...:
  • Итак, создадим новый проект. Пусть он будет называться DbApp. Вначале создадим базу данных, к которой мы будем подключаться. Для этого откроем специальную программу SQL Server 2014 Management Studio, которая устанавливается вместе с MS SQL Server и которая служит для управления базами данных. В левом древовидном меню найдем пункт Databases, нажмем на него правой кнопкой мыши и в появившемся контекстном меню выберем пункт New Database...:
 Назовем базу данных mobiledb и нажмем на кнопку OK:

Назовем базу данных mobiledb и нажмем на кнопку OK:

После этого в левом меню появится узел с только что созданной базой данных. Теперь добавим в нее таблицу. Правой кнопкой мыши нажмем на подузел Tables и в контекстном меню выберем пункт Tables...:
  • После этого в левом меню появится узел с только что созданной базой данных. Теперь добавим в нее таблицу. Правой кнопкой мыши нажмем на подузел Tables и в контекстном меню выберем пункт Tables...:
Затем нам открывается дизайнер таблицы:

Затем нам открывается дизайнер таблицы:

В нем надо указать четыре столбца: Id, Title, Company и Price, которые будут представлять соответственно уникальный идентификатор телефона, название его модели, производителя и цену. У первого и четвертого столбца надо указать тип int (то есть целочисленный), а у столбцов Title и Company - тип nvarchar (строковый).
  • В нем надо указать четыре столбца: Id, Title, Company и Price, которые будут представлять соответственно уникальный идентификатор телефона, название его модели, производителя и цену. У первого и четвертого столбца надо указать тип int (то есть целочисленный), а у столбцов Title и Company - тип nvarchar (строковый).
Кроме того, в окне свойств таблицы в поле Name надо ввести имя таблицы - Phones, а в поле Identity Column ввести Id, так как столбец Id будет идентификатором.
  • Кроме того, в окне свойств таблицы в поле Name надо ввести имя таблицы - Phones, а в поле Identity Column ввести Id, так как столбец Id будет идентификатором.
И в конце нам надо установить курсор на столбец Id и в панели инструментов программы нажать на золотой ключик. После этого напротив поля Id также должен появиться золотой ключик. Этот ключик будет указывать, что столбец Id будет выполнять роль первичного ключа.
  • И в конце нам надо установить курсор на столбец Id и в панели инструментов программы нажать на золотой ключик. После этого напротив поля Id также должен появиться золотой ключик. Этот ключик будет указывать, что столбец Id будет выполнять роль первичного ключа.
После этого нажмем на сохранение и затем на клавишу F5 (обновление), и в узле нашей базы данных появится новая таблица, которая будет называться dbo.Phones:
  • После этого нажмем на сохранение и затем на клавишу F5 (обновление), и в узле нашей базы данных появится новая таблица, которая будет называться dbo.Phones:
Stored Procedures. Нажмем на этот узел правой кнопкой мыши и в контекстном меню выберем пункт Stored Procedure...: " width="640"
  • Итак, мы создали базу данных и таблицу, и сделаем последний шаг - добавим в базу данных хранимую процедуру, которая осуществляет добавление нового объекта в базу данных. Для этого выберем в узле базы данных пункт Programmability-Stored Procedures. Нажмем на этот узел правой кнопкой мыши и в контекстном меню выберем пункт Stored Procedure...:
В центральной части программы открывается код процедуры, который генерируется по умолчанию. Заменим этот код следующим::
  • В центральной части программы открывается код процедуры, который генерируется по умолчанию. Заменим этот код следующим::
Эта процедура выполняет добавление данных. После выражения CREATE PROCEDURE идет название процедуры. Процедура называется
  • Эта процедура выполняет добавление данных. После выражения CREATE PROCEDURE идет название процедуры. Процедура называется "sp_InsertPhone", и по этому названию мы ее будем вызывать в коде C#. Название процедуры может быть любое.
Процедура имеет три входных параметра: @title, @company и @price. Через эти параметры будут передаваться значения для объекта в таблице Phones. В самом теле процедуры после выражения AS идет стандартное sql-выражение INSERT, которое выполняет добавление данных. И в конце с помощью выражения SELECT возвращается результат. Выражение SCOPE_IDENTITY() возвращает id добавленной записи, который присваивается четвертому выходному параметру @Id. Поэтому на выходе из процедуры мы получим id новой записи. И завершается процедура ключевым словом GO.
  • Процедура имеет три входных параметра: @title, @company и @price. Через эти параметры будут передаваться значения для объекта в таблице Phones. В самом теле процедуры после выражения AS идет стандартное sql-выражение INSERT, которое выполняет добавление данных. И в конце с помощью выражения SELECT возвращается результат. Выражение SCOPE_IDENTITY() возвращает id добавленной записи, который присваивается четвертому выходному параметру @Id. Поэтому на выходе из процедуры мы получим id новой записи. И завершается процедура ключевым словом GO.
Процедура имеет три входных параметра: @title, @company и @price. Через эти параметры будут передаваться значения для объекта в таблице Phones. В самом теле процедуры после выражения AS идет стандартное sql-выражение INSERT, которое выполняет добавление данных. И в конце с помощью выражения SELECT возвращается результат. Выражение SCOPE_IDENTITY() возвращает id добавленной записи, который присваивается четвертому выходному параметру @Id. Поэтому на выходе из процедуры мы получим id новой записи. И завершается процедура ключевым словом GO.
  • Процедура имеет три входных параметра: @title, @company и @price. Через эти параметры будут передаваться значения для объекта в таблице Phones. В самом теле процедуры после выражения AS идет стандартное sql-выражение INSERT, которое выполняет добавление данных. И в конце с помощью выражения SELECT возвращается результат. Выражение SCOPE_IDENTITY() возвращает id добавленной записи, который присваивается четвертому выходному параметру @Id. Поэтому на выходе из процедуры мы получим id новой записи. И завершается процедура ключевым словом GO.
Теперь подключимся к ней из приложения на WPF.

Теперь подключимся к ней из приложения на WPF.

Подключение к базе данных В любом проекте WPF, как и в ряде других типов проектов для .NET, по умолчанию есть файл конфигурации, который называется app.config и который имеет следующее содержимое:

Подключение к базе данных

  • В любом проекте WPF, как и в ряде других типов проектов для .NET, по умолчанию есть файл конфигурации, который называется app.config и который имеет следующее содержимое:
Добавим в него строку подключения к бд, изменив файл следующим образом:

Добавим в него строку подключения к бд, изменив файл следующим образом:

Для определения всех подключений в программе в пределах узла  добавляется новый узел . В этом узле определяются строки подключения с помощью элемента . Каждая строка подключения имеет название, определяемое с помощью атрибута name. В данном случае строка подключения называется
  • Для определения всех подключений в программе в пределах узла добавляется новый узел . В этом узле определяются строки подключения с помощью элемента . Каждая строка подключения имеет название, определяемое с помощью атрибута name. В данном случае строка подключения называется "DefaultConnection". Название может быть произвольное.
Атрибут connectionString собственно хранит строку подключения. Он состоит из трех частей:  Data Source=.\SQLEXPRESS: указывает на название сервера. По умолчанию для MS SQL Server Express используется
  • Атрибут connectionString собственно хранит строку подключения. Он состоит из трех частей:
  •  Data Source=.\SQLEXPRESS: указывает на название сервера. По умолчанию для MS SQL Server Express используется ".\SQLEXPRESS"
  •  Initial Catalog=mobiledb: название базы данных. Так как база данных называется mobiledb, то соответственно здесь данное название и указываем
  •  Integrated Security=True: задает режим аутентификации
Так как мы будем подключаться к базе данных MS SQL Server, то соответственно мы будем использовать провайдер для SQL Server, функциональность которого заключена в пространстве имен System.Data.SqlClient.
  • Так как мы будем подключаться к базе данных MS SQL Server, то соответственно мы будем использовать провайдер для SQL Server, функциональность которого заключена в пространстве имен System.Data.SqlClient.
Далее определим код графического интерфейса в xaml:
  • Далее определим код графического интерфейса в xaml:
Здесь определен довольно простой интерфейс: датагрид для отображения данных, и две кнопки для обновления данных в бд и для удаления. В итоге приложение будет выглядеть следующим образом:
  • Здесь определен довольно простой интерфейс: датагрид для отображения данных, и две кнопки для обновления данных в бд и для удаления. В итоге приложение будет выглядеть следующим образом:
Теперь определим код подключения и все обработчики кнопок в файле кода c#:

Теперь определим код подключения и все обработчики кнопок в файле кода c#:

Вся работа с бд производится стандартными средствами ADO.NET и прежде всего классом SqlDataAdapter. Вначале мы получаем в конструкторе строку подключения, которая определена выше в файле app.config :
  • Вся работа с бд производится стандартными средствами ADO.NET и прежде всего классом SqlDataAdapter. Вначале мы получаем в конструкторе строку подключения, которая определена выше в файле app.config :
Чтобы задействовать эту функциональность, нам надо добавить в проект библиотеку System.Configuration.dll. Далее в обработчике загрузки окна Window_Loaded создаем объект SqlDataAdapter:
  • Чтобы задействовать эту функциональность, нам надо добавить в проект библиотеку System.Configuration.dll.
  • Далее в обработчике загрузки окна Window_Loaded создаем объект SqlDataAdapter:
В качестве команды для добавления объекта устанавливаем ссылку на хранимую процедуру:
  • В качестве команды для добавления объекта устанавливаем ссылку на хранимую процедуру:
Получаем данные из БД и осуществляем привязку
  • Получаем данные из БД и осуществляем привязку
За обновление отвечает метод UpdateDB() :

За обновление отвечает метод UpdateDB() :

Чтобы обновить данные через SqlDataAdapter, нам нужна команда обновления, которую можно получить с помощью объекта SqlCommandBuilder. Для самого обновления вызывается метод adapter.Update().
  • Чтобы обновить данные через SqlDataAdapter, нам нужна команда обновления, которую можно получить с помощью объекта SqlCommandBuilder. Для самого обновления вызывается метод adapter.Update().
Причем не важно, что мы делаем в программе - добавляем, редактируем или удаляем строки. Метод adapter.Update сделает все необходимые действия. Дело в том, что при загрузке данных в объект DataTable система отслеживает состояние загруженных строк. В методе adapter.Update() состояние строк используется для генерации нужных выражений языка SQL, чтобы выполнить обновление базы данных.
  • Причем не важно, что мы делаем в программе - добавляем, редактируем или удаляем строки. Метод adapter.Update сделает все необходимые действия. Дело в том, что при загрузке данных в объект DataTable система отслеживает состояние загруженных строк. В методе adapter.Update() состояние строк используется для генерации нужных выражений языка SQL, чтобы выполнить обновление базы данных.
В обработчике кнопки обновления просто вызывается этот метод UpdateDB, а в обработчике кнопки удаления предварительно удаляются все выделенные строки.
  • В обработчике кнопки обновления просто вызывается этот метод UpdateDB, а в обработчике кнопки удаления предварительно удаляются все выделенные строки.
Таким образом, мы можем вводить в DataGrid новые данные, редактировать там же уже существующие, сделать множество изменений, и после этого нажать на кнопку обновления, и все эти изменения синхронизируются с базой данных.
  • Таким образом, мы можем вводить в DataGrid новые данные, редактировать там же уже существующие, сделать множество изменений, и после этого нажать на кнопку обновления, и все эти изменения синхронизируются с базой данных.
Причем важно отметить действие хранимой процедуры - при добавлении нового объекта данные уходят на сервер, и процедура возвращает нам id добавленной записи. Этот id играет большую роль при генерации нужного sql-выражения, если мы захотим эту запись изменить или удалить. И если бы не хранимая процедура, то нам пришлось бы после добавления данных загружать заново всю таблицу в datagrid, только чтобы у новой добавленной записи был в datagrid id. И хранимая процедура избавляет нас от этой работы.
  • Причем важно отметить действие хранимой процедуры - при добавлении нового объекта данные уходят на сервер, и процедура возвращает нам id добавленной записи. Этот id играет большую роль при генерации нужного sql-выражения, если мы захотим эту запись изменить или удалить. И если бы не хранимая процедура, то нам пришлось бы после добавления данных загружать заново всю таблицу в datagrid, только чтобы у новой добавленной записи был в datagrid id. И хранимая процедура избавляет нас от этой работы.
Причем важно отметить действие хранимой процедуры - при добавлении нового объекта данные уходят на сервер, и процедура возвращает нам id добавленной записи. Этот id играет большую роль при генерации нужного sql-выражения, если мы захотим эту запись изменить или удалить. И если бы не хранимая процедура, то нам пришлось бы после добавления данных загружать заново всю таблицу в datagrid, только чтобы у новой добавленной записи был в datagrid id. И хранимая процедура избавляет нас от этой работы.
  • Причем важно отметить действие хранимой процедуры - при добавлении нового объекта данные уходят на сервер, и процедура возвращает нам id добавленной записи. Этот id играет большую роль при генерации нужного sql-выражения, если мы захотим эту запись изменить или удалить. И если бы не хранимая процедура, то нам пришлось бы после добавления данных загружать заново всю таблицу в datagrid, только чтобы у новой добавленной записи был в datagrid id. И хранимая процедура избавляет нас от этой работы.
И если после окончания редактирования мы нажмем на Enter, то срабатывает обработчик события RowEditEnding, который обновит базу данных. Итак, здесь рассмотрен простейший способ работы с базой данных в WPF. Далее мы рассмотрим еще один способ, который подразумевает применение технологии Entity Framework.
  • И если после окончания редактирования мы нажмем на Enter, то срабатывает обработчик события RowEditEnding, который обновит базу данных.
  • Итак, здесь рассмотрен простейший способ работы с базой данных в WPF. Далее мы рассмотрим еще один способ, который подразумевает применение технологии Entity Framework.
Работа с Entity Framework Entity Framework представляет ORM-технологию, которая позволяет абстрагироваться от структуры базы данных и может выполнять автоматически сопоставление таблиц и их данных с моделями классов, определенных разработчиком.

Работа с Entity Framework

  • Entity Framework представляет ORM-технологию, которая позволяет абстрагироваться от структуры базы данных и может выполнять автоматически сопоставление таблиц и их данных с моделями классов, определенных разработчиком.
Вначале создадим новый проект. Пусть он называется EfDbApp. Первым делом нам надо добавить все необходимые пакеты Entity Framework в наш проект. Для этого в структуре проекта нажмем правой кнопкой мыши на узел References (Библиотеки) и в контекстном меню выберем пункт Manage NuGet Packages...:
  • Вначале создадим новый проект. Пусть он называется EfDbApp. Первым делом нам надо добавить все необходимые пакеты Entity Framework в наш проект. Для этого в структуре проекта нажмем правой кнопкой мыши на узел References (Библиотеки) и в контекстном меню выберем пункт Manage NuGet Packages...:
В открывшемся менеджере пакетов NuGet выберем пакет Entity Framework и установим его:
  • В открывшемся менеджере пакетов NuGet выберем пакет Entity Framework и установим его:
Затем определим строку подключения в файле App.config :

Затем определим строку подключения в файле App.config :

В данном случае мы будем использовать ту же базу данных mobiledb, которую создали в предыдущих темах. Однако даже если у нас нет базы данных mobiledb, то при первом обращении к базе данных Entity Framework создаст ее автоматически.
  • В данном случае мы будем использовать ту же базу данных mobiledb, которую создали в предыдущих темах. Однако даже если у нас нет базы данных mobiledb, то при первом обращении к базе данных Entity Framework создаст ее автоматически.
Теперь добавим в проект новую папку, которую назовем Models и в которой определим новый класс Phone:
  • Теперь добавим в проект новую папку, которую назовем Models и в которой определим новый класс Phone:
Для взаимодействия с базой данных через Entity Framework нам нужен контекст данных, поэтому добавим в папку Models еще один класс, который назовем MobileContext:
  • Для взаимодействия с базой данных через Entity Framework нам нужен контекст данных, поэтому добавим в папку Models еще один класс, который назовем MobileContext:
Класс контекста наследуется от класса DbContext. В своем конструкторе он передает в конструктор базового класса название строки подключения из файла App.config . Также в контексте данных определяется свойство по типу DbSet - через него мы будем взаимодействовать с таблицей, которая хранит объекты Phone.
  • Класс контекста наследуется от класса DbContext. В своем конструкторе он передает в конструктор базового класса название строки подключения из файла App.config . Также в контексте данных определяется свойство по типу DbSet - через него мы будем взаимодействовать с таблицей, которая хранит объекты Phone.
Теперь определим разметку интерфейса:

Теперь определим разметку интерфейса:

На форме будет один элемент DataGrid и две кнопки для обновления и удаления.

На форме будет один элемент DataGrid и две кнопки для обновления и удаления.

Теперь определим в файле кода c# привязку данных и обработчики кнопок:

Теперь определим в файле кода c# привязку данных и обработчики кнопок:

С помощью следующих строк здесь мы загружаем данные из бд и выполняем привязку к ним элемента DataGrid:
  • С помощью следующих строк здесь мы загружаем данные из бд и выполняем привязку к ним элемента DataGrid:
После окончания работы с контекстом данных нам нужно его утилизовать, а именно вызвать его метод Dispose(). Подходящим местом для этого является обработчик события Closing класса MainWindow.
  • После окончания работы с контекстом данных нам нужно его утилизовать, а именно вызвать его метод Dispose(). Подходящим местом для этого является обработчик события Closing класса MainWindow.
И как и в прошлой теме, здесь нам достаточно ввести данные в строку грида, чтобы создать новый объект. Также мы можем изменять уже существующие значения в ячейках грида. И чтобы сохранить все изменения, в обработчике кнопки обновления вызывается метод db.SaveChanges(). Для удаления данных сначала вызывается метод db.Phones.Remove(phone) для всех удаляемых объектов, а затем также метод db.SaveChanges.
  • И как и в прошлой теме, здесь нам достаточно ввести данные в строку грида, чтобы создать новый объект. Также мы можем изменять уже существующие значения в ячейках грида. И чтобы сохранить все изменения, в обработчике кнопки обновления вызывается метод db.SaveChanges().
  • Для удаления данных сначала вызывается метод db.Phones.Remove(phone) для всех удаляемых объектов, а затем также метод db.SaveChanges.