Локальные базы данных
Рассмотрим код файла 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.