Локальные базы данных
В Листинге 35.3 приведен код файла ToDoDataContext.cs
using System; using System.ComponentModel; using System.Data.Linq; using System.Data.Linq.Mapping; namespace LocalDatabaseSample.Model { public class ToDoDataContext : DataContext { // Передача строки соединения базовому классу. public ToDoDataContext(string connectionString) : base(connectionString) { } // Указание таблицы для элементов. public Table<ToDoItem> Items; // Указание таблицы для категорий. public Table<ToDoCategory> Categories; } [Table] public class ToDoItem : INotifyPropertyChanged, INotifyPropertyChanging { // Определяет ID: закрытое поле, общедоступное поле, и столбец в таблице базы данных. private int _toDoItemId; [Column(IsPrimaryKey = true, IsDbGenerated = true, DbType = "INT NOT NULL Identity", CanBeNull = false, AutoSync = AutoSync.OnInsert)] public int ToDoItemId { get { return _toDoItemId; } set { if (_toDoItemId != value) { NotifyPropertyChanging("ToDoItemId"); _toDoItemId = value; NotifyPropertyChanged("ToDoItemId"); } } } // Определяет имя элемента: закрытое поле, общедоступное поле, и столбец в таблице базы данных. private string _itemName; [Column] public string ItemName { get { return _itemName; } set { if (_itemName != value) { NotifyPropertyChanging("ItemName"); _itemName = value; NotifyPropertyChanged("ItemName"); } } } // Определяет значение завершения: закрытое поле, общедоступное поле, и столбец в таблице базы данных. private bool _isComplete; [Column] public bool IsComplete { get { return _isComplete; } set { if (_isComplete != value) { NotifyPropertyChanging("IsComplete"); _isComplete = value; NotifyPropertyChanged("IsComplete"); } } } // Столбец для определения производительности обновления. [Column(IsVersion = true)] private Binary _version; // Колонка Internal для связанного значения ID ToDoCategory [Column] internal int _categoryId; // Ссылка на сущность, для идентификации таблицы ToDoCategory "хранилища" private EntityRef<ToDoCategory> _category; // Ассоциация, для описания взаимосвязи между данным ключом и таблицей "хранилища" [Association(Storage = "_category", ThisKey = "_categoryId", OtherKey = "Id", IsForeignKey = true)] public ToDoCategory Category { get { return _category.Entity; } set { NotifyPropertyChanging("Category"); _category.Entity = value; if (value != null) { _categoryId = value.Id; } NotifyPropertyChanging("Category"); } } #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; // Используется для выдачи уведомлений о том, что свойство изменено private void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } #endregion #region INotifyPropertyChanging Members public event PropertyChangingEventHandler PropertyChanging; // Используется для выдачи уведомлений о том, что свойство может измениться private void NotifyPropertyChanging(string propertyName) { if (PropertyChanging != null) { PropertyChanging(this, new PropertyChangingEventArgs(propertyName)); } } #endregion } [Table] public class ToDoCategory : INotifyPropertyChanged, INotifyPropertyChanging { // Определяет ID: закрытое поле, общедоступное поле, и столбец в таблице базы данных. private int _id; [Column(DbType = "INT NOT NULL IDENTITY", IsDbGenerated = true, IsPrimaryKey = true)] public int Id { get { return _id; } set { NotifyPropertyChanging("Id"); _id = value; NotifyPropertyChanged("Id"); } } // Определяет имя категории: закрытое поле, общедоступное поле, и столбец в таблице базы данных private string _name; [Column] public string Name { get { return _name; } set { NotifyPropertyChanging("Name"); _name = value; NotifyPropertyChanged("Name"); } } // Столбец для определения производительности обновления. [Column(IsVersion = true)] private Binary _version; // Определяет набор сущностей для той стороны взаимодействия, которая имеет отношение к коллекции private EntitySet<ToDoItem> _todos; [Association(Storage = "_todos", OtherKey = "_categoryId", ThisKey = "Id")] public EntitySet<ToDoItem> ToDos { get { return this._todos; } set { this._todos.Assign(value); } } // Назначение обработчиков для операций добавления и удаления, соответственно public ToDoCategory() { _todos = new EntitySet<ToDoItem>( new Action<ToDoItem>(this.attach_ToDo), new Action<ToDoItem>(this.detach_ToDo) ); } // Вызывается в ходе операции добавления private void attach_ToDo(ToDoItem toDo) { NotifyPropertyChanging("ToDoItem"); toDo.Category = this; } // Вызывается в ходе операции удаления private void detach_ToDo(ToDoItem toDo) { NotifyPropertyChanging("ToDoItem"); toDo.Category = null; } #region INotifyPropertyChanged Members public event PropertyChangedEventHandler PropertyChanged; // Используется для выдачи уведомлений о том, что свойство изменено private void NotifyPropertyChanged(string propertyName) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); } } #endregion #region INotifyPropertyChanging Members public event PropertyChangingEventHandler PropertyChanging; // Используется для выдачи уведомлений о том, что свойство может измениться private void NotifyPropertyChanging(string propertyName) { if (PropertyChanging != null) { PropertyChanging(this, new PropertyChangingEventArgs(propertyName)); } } #endregion } }Листинг 35.3. Файл ToDoDataContext.cs
Подробные сведения о разработке приложений, использующих базы данных, можно найти в материале "Локальная база данных для Windows Phone" (http://msdn.microsoft.com/en-us/library/windowsphone/develop/hh202860%28v=vs.105%29.aspx).
Для того, чтобы изучить пример разработки простой локальной базы данных для Windows Phone, без использовании шаблона проектирования MVVM, обратитесь к материалу "Как создать простое приложение для Windows Phone, работающее с базой данных" (http://msdn.microsoft.com/ru-RU/library/windowsphone/develop/hh202876%28v=vs.105%29.aspx).
Для того, чтобы найти дополнительные материалы по Linq to SQL, обратитесь к ресурсу "Linq to SQL" (http://msdn.microsoft.com/ru-ru/library/bb386976.aspx).
Выводы
Приложения для Windows Phone 8 могут хранить реляционные данные в локальных базах данных, с помощью механизмов Linq to SQL обеспечивается объектное представление баз данных в приложениях, что позволяет организовать удобную работу с ними.
Задание
Если приложение, созданием которого вы занимаетесь, подразумевает работу с данными, имеющими сложную структуру, рассмотрите возможность использования локальной базы данных для работы с ними. Кроме того, если приложение рассчитано на работу с локальной базой данных, это упростит, при необходимости, возможность перехода на использование облачной базы данных, работающей на платформе Windows Azure с использованием локальной базы данных в качестве локального кэша. Подготовьте отчёт по данному этапу работы, приведите в нём анализ данных, которые использует приложение и сделайте выводы о том, поможет ли использование базы данных улучшить структуру вашего приложения.
Для того, чтобы спроектировать базу данных для приложения вам могут понадобиться дополнительные знания, для того, чтобы их получить, вы можете обратиться к учебным курсам, посвященным базам данных на портале Intuit.ru (например, к курсу "Введение в реляционные базы данных", http://www.intuit.ru/studies/courses/74/74/info.
Дополнительные материалы
К данной лабораторной работе подготовлено видеоприложение.