четверг, 2 февраля 2012 г.

Win Forms. Общаемся с БД

Идеология Win Forms приложений проста: есть окно с некими элементами управления в них. Элементы управления генерируют события. Когда пользователь нажимаем на кнопку - она генерит событие, что на нее нажали.

Нечто подобное мы делали тут.

Создаем Windows Forms Application.

 

View - Toolbox
All Windows Forms –
тут нам понадобятся кнопки (Button) и таблички (DataGridView)


Вытащили кнопку – назвали в свойствах «Добавление жанра».
Клац-клац по ней – попадаем в код.
Что нам надо сделать, чтобы добавить жанр? Обратиться к базе данных. С помощью некой операции, в данном случае Insert. А как уже писалось, чтобы совершить операцию, надо открыть транзакцию (а потом ее закрыть)

Открываем

var tran = connection.BeginTransaction(IsolationLevel.ReadCommitted)

Закрываем

tran.Dispose();

Однако при таком подходе, если у нас что-то пойдет не так – например, отвалится соединение, код не доработает до второй строки => транзакция не будет закрыта.
Поэтому оборачиваем использование транзакции в оператор using
using (var tran = connection.BeginTransaction(IsolationLevel.ReadCommitted))
{  код внутри транзакции  }
Уровень изоляции выбираем, исходя из нужд приложения. Нам вполне хватит ReadCommitted.

Транзакция, в свою очередь, обращается к соединению – перед тем, как открыть транзакцию, надо открыть соединение. В целях экономии ресурсов использование соединения также оборачивается в оператор using.
Что делает оператор using ? В приведенном ниже примере conn и conn2 идентичны. Но один расписан в 9 строк, а второй делает ровно тоже самое - в одну. А именно - защищает от проблем в коде, в любом случае выполняя завуалированный блок finally, по умолчанию делающий Dispose переменной, указанной в операторе using  
На выходе получаем код:
Внутри транзакции мы создаем новый объект типа «Жанр», присваиваем ему некое имя. После чего выполняем операцию Insert, записывая ее итог в переменную count, для того, чтобы вывести сообщение о том, что строка корректно добавилась, что и сделано после коммита транзакции.
Класс «Жанр» содержит в себе:
Поля id и name, а также их геттеры/сеттеры:
        private int id;
        private string name;

        public int Id
        {
            get { return id; }
            set { id = value; }
        }

        public string Name
        {
            get { return name; }
            set { name = value; }
        }

Методу  Insert мы будем передавать жанр, соединение типа SqlConnection и транзакцию типа SqlTransaction.

После чего создаем SQL команду, которой говорим «добавить в таблицу жанров значение с именем…». Чтобы обозначить передаваемый параметр, ставим собачку перед этим параметром: «@name».

Так как мы создаем новую строку, у которой формируется id, нам надо это id получить. Получаем мы его с помощью комады @@IDENTITY. Она возвращает последнее значение изменения автоинкрементального поля.

После чего с помощью команд

cmd.Parameters.Add(*параметры*);

Добавляем оба параметра в эту команду. Запись вида

new SqlParameter("id", SqlDbType.Int) { Direction = ParameterDirection.Output };

Говорит о том, что id – выходной параметр. Если мы просто указываем новый SQL параметр без каких либо значений в фигурных скобках – по дефолту это входной параметр (Direction = ParameterDirection.Input). Но значение id мы должны получить, а не записать => это выходной параметр.

Записали параметры в cmd, потом указали, что она выполняется в рамках транзакции, перевадаемой методу. И сконвертировали значение полученной id в значение типа int

Метод Update выглядит проще, так как там нам не надо получать параметры


Вот и все, будем теперь по кнопке выполнять какое-то действие, еще и получать корректное сообщение об этом благодаря оператору MessageBox

Теперь о таблицах. Достаем ее на форму – правой кнопкой, edit colums
.

Создаем нужные нам колонки, закрываем. HeаderText - название самой колонки, DataPropertyName - имя свойства объекта, которое мы будем тащить в эту таблицу.


Делаем рядом кнопку «Get Жанры» или «Получить Жанры». Ее код:

За отображение полученного листа информации в таблице отвечает код

dgGenres.DataSource = list;

dgGenres – название нашей таблички, задаем его в Properties

Ну и сам метод получения жанров (в классе Genre.cs). Ему уже не надо передавать объект типа жанр, только соединение и транзакцию.


















Ну и чтобы у нас все работало, нам надо указать - к какой такой Базе Данных мы обращаемся?
Добавляем в проект новый item:


Называем его волшебным словом «App.config», прописываем там строку соединения:

<?xml version="1.0" encoding="utf-8" ?>
<configuration>
  <connectionStrings>
    <add name ="default" connectionString="Data Source=.\SQLEXPRESS;Initial Catalog=Books;Persist Security Info=True;User ID=ap;Password="></add>
  </connectionStrings>
</configuration>

Теперь можно запускать и наслаждаться результатом.

Это уже и автоматизировать можно... Правда, сложно :)
Если работаешь с Web, то и к базе надо обращаться через Web...

Комментариев нет:

Отправить комментарий