Работа с Windows Azure Table
Задача 3. Редактирование и удаление сущностей
По своей сути задачи редактирование и удаления сущностей конкретной таблицы весьма проста. Достаточно вызвать соответствующие методы класса - контекста. Однако, в качестве параметров методов выступают изменяемые сущности. Таким образом, все сводится к выделению конкретной сущности из таблицы по ее ключам секции и строки, которые, напомним, являются частями уникального ключа сущности.
Поскольку нашей целью является демонстрация работы с Windows Azure Table, мы пойдем по самому простому пути.
Для начала добавим на форму кнопку btn_change, невидимую при загрузке страницы.
Данные между методами формы будем передавать при помощи сессий.
Первая и главная задача сводится к тому, чтобы определить ключи строки и секции редактируемой сущности. Учитывая, что структура таблицы и названия параметров могут быть произвольны, за одним исключением - как раз параметров Partition Key и Row Key , добавим в метод Page_Load следующее:
int i = 0;
foreach (TableCell cell in contactGV.HeaderRow.Cells)
{
if (cell.Text == "PartitionKey") { Session["pkindex"] = i; }
if (cell.Text == "RowKey") { Session["rkindex"] = i; }
i++;
}Теперь, вне зависимости от структуры таблицы, сессии pkindex и rkindex будут содержать номера столбцов contactGV , в которых находятся параметры ключей секции и строки.
Полностью метод Page_Load для данного задания должен быть следующим:
protected void Page_Load(object sender, EventArgs e)
{
btn_change.Visible = false;
account = CloudStorageAccount.FromConfigurationSetting("DataConnectionString");
context = new ContactContext(account.TableEndpoint, account.Credentials);
contactGV.DataSource = context.ContactData;
contactGV.DataBind();
int i = 0;
foreach (TableCell cell in contactGV.HeaderRow.Cells)
{
if (cell.Text == "PartitionKey") { Session["pkindex"] = i; }
if (cell.Text == "RowKey") { Session["rkindex"] = i; }
i++;
}
}Также добавим в класс ContactContext методы для обновления и удаления сущностей - Update и Delete соответственно:
public void Delete(Contact cnt)
{
this.DeleteObject(cnt);
this.SaveChanges();
}
public void Update(Contact cnt)
{
this.UpdateObject(cnt);
this.SaveChanges();
}Удаление строки
Добавим метод, обрабатывающий нажатие кнопки "Удалить" элемента contactGV.
protected void contactGV_RowDeleting(object sender, GridViewDeleteEventArgs e)
{
GridView g = (GridView)sender;
try
{
Contact c = (from contact in context.CreateQuery<Contact>("Contacts")
where contact.PartitionKey == g.Rows[e.RowIndex].
Cells[Convert.ToInt32(Session["pkindex"].ToString())].Text
&& contact.RowKey == g.Rows[e.RowIndex].Cells[Convert.ToInt32
(Session["rkindex"].ToString())].Text
select contact).FirstOrDefault();
context.Delete(c);
}
catch(DataServiceRequestException ex)
{
lb_status.Text = ex.Message;
}
g.DataBind();
}Обратим ваше внимание на то, что сущность для удаления мы получаем при помощи linq - запроса, указывая значения параметров PartitionKey и RowKey . Значения же параметров мы получаем из contactGV , указывая значения соответствующих ячеек.
Реализация удаления сущности на этом закончена.
Редактирование сущности
Для начала напишем обработчик события изменения индекса выбранной строки contactGV , инициируемое нажатием кнопки "Изменить" . При нажатии этой кнопки должен становиться видимым элемент управления btn_change, а соответствующие текстовые поля заполняться значениями параметров редактируемой строки.
protected void contactGV_SelectedIndexChanged(object sender, EventArgs e)
{
GridView g = (GridView)sender;
int index = g.SelectedIndex;
Contact c = (from contact in context.CreateQuery<Contact>("Contacts")
where contact.PartitionKey == g.Rows[index].
Cells[Convert.ToInt32(Session["pkindex"].ToString())].Text
&& contact.RowKey == g.Rows[index].
Cells[Convert.ToInt32(Session["rkindex"].ToString())].Text
select contact).FirstOrDefault();
tb_firstname.Text = c.FirstName;
tb_lastname.Text = c.LastName;
tb_email.Text = c.Email;
tb_telnum.Text = c.TelNumber;
Session["index"] = index;
btn_change.Visible = true;
}Здесь стоит обратить внимание разве что на формирование еще одной сессии, в которой мы будем хранить номер редактируемой строки в contactGV.
Вот, что должно получиться при нажатии кнопки "Изменить" напротив второй строки списка контактов:
Как видим, значения текстовых полей стали соответствовать значениям параметров редактируемой строки.
Осталось только написать метод обрабатывающий событие нажатия кнопки btn_change.
Он будет выглядеть следующим образом:
protected void btn_change_Click(object sender, EventArgs e)
{
int index = Convert.ToInt32(Session["index"].ToString());
try
{
Contact c = (from contact in context.CreateQuery<Contact>("Contacts")
where contact.PartitionKey == contactGV.Rows[index].
Cells[Convert.ToInt32(Session["pkindex"].ToString())].Text
&& contact.RowKey == contactGV.Rows[index].
Cells[Convert.ToInt32(Session["rkindex"].ToString())].Text
select contact).FirstOrDefault();
c.FirstName = tb_firstname.Text;
c.LastName = tb_lastname.Text;
c.Email = tb_email.Text;
c.TelNumber = tb_telnum.Text;
context.Update(c);
}
catch (DataServiceRequestException a)
{
lb_status.Text = a.Message;
}
contactGV.DataBind();
}Номер изменяемой строки мы получаем из сессии "index" , остальное уже не должно вызывать вопросов.
Запустите приложение еще раз и измените произвольным образом любой из параметров, либо насколько из них какой - либо строки. Мы изменили Email на tableentitychange@mail.test . Нажмите кнопку "Change".
Мы получили следующее:
Еще раз обратим ваше внимание на то, что демонстрируемое приложение является не более, чем примером способов работы с Windows Azure Storage, поэтому мы пренебрегли обработкой исключительных ситуаций и проверкой правильности и целостности введенных данных. Оставляем это на ваше усмотрение.
В случае, если выполнение задания вызвало сложности и затруднения, в приложениях к данной практической работе вы найдете итоговый программный код в том виде, в котором он необходим для Задания№3.

