Опубликован: 08.07.2011 | Доступ: свободный | Студентов: 1788 / 93 | Оценка: 4.15 / 4.08 | Длительность: 15:28:00
Самостоятельная работа 2:

Разработка Silverlight-приложения

< Лекция 7 || Самостоятельная работа 2: 12345 || Лекция 8 >

Задание 5. Разработать методы манипулирования данными – 2 часа.

Редактирование данных

Для редактирования данных необходимо обеспечить возможность изменения детальных данных, что реализуется нажатием кнопки Редактировать. С учетом того, что для элементов управления детальными данными выполнена двусторонняя привязка данных ( Mode=TwoWay ), то изменения в детальных данных будут приводить к изменению данных в контексте сущностей, связанных со списком listBox. После редактирования данных необходимо проведенные изменения сохранить в базе данных. Для этого модифицируйте метод Save_Click, добавив в него следующую строку:

context.BeginSaveChanges(SaveChangesOptions.Batch, OnChangesSaved, context);

Измененный код метода Save_Click будет иметь следующий вид:

private void Save_Click(object sender, RoutedEventArgs e)
{
    context.BeginSaveChanges(SaveChangesOptions.Batch, OnChangesSaved, context);
    ReadOnly(false);
    ButtonIsEnabled(true);
    listBoxEmployees.IsEnabled = true;
}

Метод BeginSaveChanges() класса DataServiceContent запускает асинхронную операцию сохранения данных, изменение которых были проведены в контексте сущностей PersonalEntities. Перечисление SaveChangesOptions.Batch определяет, что все проведенные изменения сохраняются в составе одного пакетного запроса. Вторым параметром метода BeginSaveChanges() является делегат, который ссылается на метод OnChangesSaved(). Метод OnChangesSaved() обрабатывает результат этой асинхронной операции путем вызова метода EndSaveChanges(), анализа возвращаемых объектов OperationResponse и печати кодов состояния ответа.

private void OnChangesSaved(IAsyncResult result)
{
    Dispatcher.BeginInvoke(() =>
    {
        context = result.AsyncState as PersonalEntities;
        try
        {
            WriteOperationResponse(context.EndSaveChanges(result));
        }
        catch (DataServiceRequestException ex)
        {
                   MessageBox.Show( WriteOperationResponse(ex.Response));
        }
        catch (InvalidOperationException ex)
        {
            MessageBox.Show(ex.Message);
        }
    }
    );
}

Метод WriteOperationResponse() обеспечивает формирование информации при сохранении данных.

private string WriteOperationResponse(DataServiceResponse response)
{
    string mes = string.Empty;
    int i = 1;
    if (response.IsBatchResponse)
    {
        mes = string.Format("Коды серии операций сохранения: {0}\n",
            response.BatchStatusCode);
    }
    foreach (ChangeOperationResponse change in response)
    {
        mes +=
            string.Format("\tИзменение {0} code: {1}\n",
            i.ToString(), change.StatusCode.ToString());
        if (change.Error != null)
        {
            string.Format("\tИзменение {0} error: {1}\n",
                i.ToString(), change.Error.Message);
        }
        i++;
    }
    return mes;
}

Проведенные изменения обеспечивают для разрабатываемого приложения возможность редактирования данных и сохранение изменений в базе данных.

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

Создание новых записей в базе данных рассматривается на примере базы Personal.

Для создания новых записей в базе данных изменим код метода New_Click().

private void New_Click(object sender, RoutedEventArgs e)
{
    Employee newEmployee = 
                   Employee.CreateEmployee(0, "не задано", "не задано", 0, "не задано");
    newEmployee.Access = "не задано";
    newEmployee.EmployeeStatus = 0;
    newEmployee.NetName = "guest";
    newEmployee.FirstDate = DateTime.Now;
    try
    {
        context.AddToEmployees(newEmployee);
        context.BeginSaveChanges(SaveChangesOptions.Batch, OnChangesSaved, context);
        employees.Add(newEmployee);
        int count = listBoxEmployees.Items.Count;
        listBoxEmployees.SelectedIndex = count - 1;
        ButtonIsEnabled(false);
        ReadOnly(true);
        listBoxEmployees.IsEnabled = false;
    }
    catch (DataServiceRequestException ex)
    {
        MessageBox.Show("Ошибка добавления нового сотрудника в базу данных");
    }
}

Вначале для класса Employee модели сущностей Personal создайте новый экземпляр newEmployee с помощью метода CreateEmployee():

Employee newEmployee=Employee.CreateEmployee(0,
			"не задано","не задано",0,"не задано");

Метод CreateEmployee() автоматически сгенерирован при создании EDM-модели сущностей и в качестве параметров использует только обязательные поля таблицы Employee базы данных Personal. Следующие строки кода предназначены для задания необязательных полей таблицы Employee ( Access, EmployeeStatus, NetName и FirstDate ):

newEmployee.Access = "не задано";
newEmployee.EmployeeStatus = 0;
newEmployee.NetName = "guest";
newEmployee.FirstDate = DateTime.Now;

Добавьте новую сущность newEmployee в модель Personal:

context.AddToEmployees(newEmployee);

при этом используется метод AddToEmployees().

Затем посредством метода BeginSaveChanges() класса DataServiceContent проведите сохранение данных в контексте сущностей PersonalEntities.

context.BeginSaveChanges(SaveChangesOptions.Batch, OnChangesSaved, context);

Для продолжения работы приложения необходимо внести изменения в коллекцию employees.

employees.Add(newEmployee);

и установить фокус в списке listBoxEmployees на созданной записи:

int count = listBoxEmployees.Items.Count;
listBoxEmployees.SelectedIndex = count - 1;

Удаление данных по сотруднику

Для удаления данных в базе данных необходимо определить экземпляр удаляемого объекта, например из списка listBox.

Employee emp = (Employee)listBoxEmployees.SelectedItem;

Затем удалить экземпляр класса Employee из контекста сущностей PersonalEntities с помощью метода DeleteObject().

context.DeleteObject(emp);

После изменения индекса выделения в списке listBoxEmployees необходими удалить экземпляр emp класса Employee из коллекции employees.

listBoxEmployees.SelectedIndex =
       listBoxEmployees.SelectedIndex == 0 ? 1 : listBoxEmployees.SelectedIndex - 1;
employees.Remove(emp);

Посредством метода BeginSaveChanges() класса DataServiceContent запустите сохранение изменений при удалении данных из контекста сущностей PersonalEntities.

context.BeginSaveChanges(SaveChangesOptions.Batch, OnChangesSaved, context);

Окончательный код метода Delete_Click() будет иметь следующий вид.

private void Delete_Click(object sender, RoutedEventArgs e)
{
    Employee emp = (Employee)listBoxEmployees.SelectedItem;
    MessageBoxResult result = MessageBox.Show("Удалить сотрудника: 
      " + emp.EmployeeSurname + " " + emp.EmployeeName + 
        " " + emp.EmployeePatronymic,
                   "Предупреждение", MessageBoxButton.OKCancel);
    if (result == MessageBoxResult.OK)
    {
        context.DeleteObject(emp);
        listBoxEmployees.SelectedIndex =
        listBoxEmployees.SelectedIndex == 0 ? 1 : listBoxEmployees.SelectedIndex - 1;
        employees.Remove(emp);
        context.BeginSaveChanges(SaveChangesOptions.Batch, OnChangesSaved, context);
    }
}
< Лекция 7 || Самостоятельная работа 2: 12345 || Лекция 8 >
Александр Петров
Александр Петров

При загрузке данных из БД возникает исключение InvalidOperationException с сообщением: Элемент коллекции должен быть пустым перед использованием ItemsSource. Знаю, что для заполнения DataGrid можно использовать коллекции Items или ItemsSource, но одновременно их использовать нельзя: если задано значение для свойства ItemsSource и в коде C# добавляется элемент в Items, возникает исключение. 
Вопрос, как отследить и отключить добавление элемента в Items?

Максим Спиридонов
Максим Спиридонов

В пятой лекции на второй странице в компиляторе выскакивает ошибка в строчке :

ObjectQuery<Employee> employees = DataEntitiesEmployee.Employees;

Ошибка CS0029

Не удается неявно преобразовать тип "System.Data.Entity.DbSet<WpfApplProject.Employee>" в "System.Data.Entity.Core.Objects.ObjectQuery<WpfApplProject.Employee>".

в using прописал все как положено, здесь похоже именно с преобразованием типов проблемы