Локальные базы данных
Рассмотрим код файла ToDoViewModel.cs, Листинг 35.2.
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
// Директива для работы с моделью данных.
using LocalDatabaseSample.Model;
namespace LocalDatabaseSample.ViewModel
{
public class ToDoViewModel : INotifyPropertyChanged
{
// Контекст данных LINQ to SQL для доступа к локальной базе данных.
private ToDoDataContext toDoDB;
// Конструктор класса, создание объекта контекста данных.
public ToDoViewModel(string toDoDBConnectionString)
{
toDoDB = new ToDoDataContext(toDoDBConnectionString);
}
// Коллекция, отображающая все элементы.
private ObservableCollection<ToDoItem> _allToDoItems;
public ObservableCollection<ToDoItem> AllToDoItems
{
get { return _allToDoItems; }
set
{
_allToDoItems = value;
NotifyPropertyChanged("AllToDoItems");
}
}
// Коллекция, отображающая элементы категории home.
private ObservableCollection<ToDoItem> _homeToDoItems;
public ObservableCollection<ToDoItem> HomeToDoItems
{
get { return _homeToDoItems; }
set
{
_homeToDoItems = value;
NotifyPropertyChanged("HomeToDoItems");
}
}
// Коллекция, отображающая элементы категории work.
private ObservableCollection<ToDoItem> _workToDoItems;
public ObservableCollection<ToDoItem> WorkToDoItems
{
get { return _workToDoItems; }
set
{
_workToDoItems = value;
NotifyPropertyChanged("WorkToDoItems");
}
}
// Коллекция, отображающая элементы категории hobbies.
private ObservableCollection<ToDoItem> _hobbiesToDoItems;
public ObservableCollection<ToDoItem> HobbiesToDoItems
{
get { return _hobbiesToDoItems; }
set
{
_hobbiesToDoItems = value;
NotifyPropertyChanged("HobbiesToDoItems");
}
}
// Список всех категорий, который используется страницей, выполняющей добавление задач.
private List<ToDoCategory> _categoriesList;
public List<ToDoCategory> CategoriesList
{
get { return _categoriesList; }
set
{
_categoriesList = value;
NotifyPropertyChanged("CategoriesList");
}
}
// Запись изменений в базу данных.
public void SaveChangesToDB()
{
toDoDB.SubmitChanges();
}
// Запрос к базе данных и загрузка коллекций и списка, которые используются главной страницей
public void LoadCollectionsFromDatabase()
{
// Запрос на получение всех элементов из базы данных.
var toDoItemsInDB = from ToDoItem todo in toDoDB.Items
select todo;
// Заполнение списка, содержащего все элементы базы.
AllToDoItems = new ObservableCollection<ToDoItem>(toDoItemsInDB);
// Запрос на получение всех категорий из базы данных.
var toDoCategoriesInDB = from ToDoCategory category in toDoDB.Categories
select category;
// Запрос к базе данных с загрузкой всех элементов в соответствующие им категории
foreach (ToDoCategory category in toDoCategoriesInDB)
{
switch (category.Name)
{
case "Home":
HomeToDoItems = new ObservableCollection<ToDoItem>(category.ToDos);
break;
case "Work":
WorkToDoItems = new ObservableCollection<ToDoItem>(category.ToDos);
break;
case "Hobbies":
HobbiesToDoItems = new ObservableCollection<ToDoItem>(category.ToDos);
break;
default:
break;
}
}
// Загрузка списка всех категорий.
CategoriesList = toDoDB.Categories.ToList();
}
// Добавление нового элемента в базу данных и в коллекцию.
public void AddToDoItem(ToDoItem newToDoItem)
{
// Добавление нового элемента в контекст данных.
toDoDB.Items.InsertOnSubmit(newToDoItem);
// Сохранение изменений в базе данных.
toDoDB.SubmitChanges();
// Добавление элемента в коллекцию, которая используется для отображения всех элементов
AllToDoItems.Add(newToDoItem);
// Добавление элемента в коллекцию, соответствующую его категории.
switch (newToDoItem.Category.Name)
{
case "Home":
HomeToDoItems.Add(newToDoItem);
break;
case "Work":
WorkToDoItems.Add(newToDoItem);
break;
case "Hobbies":
HobbiesToDoItems.Add(newToDoItem);
break;
default:
break;
}
}
// Удаление элемента из базы данных и из коллекции.
public void DeleteToDoItem(ToDoItem toDoForDelete)
{
// Удаление элемента из коллекции, которая используется для отображения всех элементов.
AllToDoItems.Remove(toDoForDelete);
// Удаление элемента из контекста данных.
toDoDB.Items.DeleteOnSubmit(toDoForDelete);
// Удаление элемента из соответствующей ему категории.
switch (toDoForDelete.Category.Name)
{
case "Home":
HomeToDoItems.Remove(toDoForDelete);
break;
case "Work":
WorkToDoItems.Remove(toDoForDelete);
break;
case "Hobbies":
HobbiesToDoItems.Remove(toDoForDelete);
break;
default:
break;
}
// Сохранение элементов в базе данных.
toDoDB.SubmitChanges();
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
// Генерирует уведомления для системы связывания данных об изменении свойства
private void NotifyPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
}
}
Листинг
35.2.
Код файла ToDoViewModel.cs
В конструкторе класса создаётся новый объект ToDoDataContext с использованием строки соединения, которая передаётся в этот конструктор при создании объекта ToDoViewModel в классе App.
Далее, выполняется загрузка данных из базы (LoadCollectionsFromDataBase()) и запись их в соответствующие коллекции. Коллекции используются при привязке данных для отображения списков элементов.
Здесь же определены методы, которые используются для добавления новых данных в базу данных (AddToDoItem), и удаления (DeleteToDoItem). При модификации состава данных в базе данных производится и соответствующая модификация коллекций, которые используются для отображения данных в интерфейсе.
В файле ToDoDataContext.cs имеется класс ToDoDataContext, он является наследником DataContext, при создании экземпляра класса передаёт родительскому классу строку соединения и задаёт два открытых поля типа Table<>, используя классы, представляющие собой объектные представления таблиц (классы сущностей) базы данных, описанные в этом же файле. А именно, речь идёт о классах ToDoItem и ToDoCategory, объявленных с атрибутом [Table]. Фактически, эти классы, во-первых, содержат описания структуры таблиц (полей таблицы, или столбцов, объявленных с атрибутом [Column]) и логику, необходимую для реализации интерфейсов INotifyPropertyChanged и INotifyPropertyChanging.