среда, 20 января 2010 г.

Изучаю Microsoft Sync Framework. Клиент.

Итак. Слой доступа к данным, как я говорил ранее, реализован спомощью Entity Framework. Собственно описывать тут особо нечего, большая часть кода генерируется автоматически.



После работы мастера, у меня появилось два класса:
PhoneRefEntities - наследник от System.Data.Objects.ObjectContext
Stuff - наследник от System.Data.Objects.DataClasses.EntityObject
Для удобства немного расширил класс PhoneRefEntities, добавив в него статическое свойство Instance:
Copy Source | Copy HTML
  1. namespace PhoneRef.Data {
  2.     partial class PhoneRefEntities {
  3.         private static PhoneRefEntities _instance;
  4.         private static readonly object SyncRoot = new object();
  5.  
  6.         public static PhoneRefEntities Instance {
  7.             get {
  8.                 lock (SyncRoot) {
  9.                     if (_instance == null)
  10.                         _instance = new PhoneRefEntities();
  11.                 }
  12.                 return _instance;
  13.             }
  14.         }
  15.     }
  16. }

Sql Server Compact не позволяет создавать связи внутри одной таблицы, поэтому свойство Parent тоже пришлось реализовать вручную:
Copy Source | Copy HTML
  1. private Stuff _parent;
  2. /// <summary>
  3. /// Руководитель
  4. /// </summary>
  5. public Stuff Parent {
  6.     get {
  7.         //SQL Server Compact не позволяет создавать связки на внутри одной таблицы
  8.         // поэтому реализуем ее таким образом.
  9.         return _parent ??
  10.                (_parent = PhoneRefEntities.Instance.Stuff.FirstOrDefault(item => item.Id == ParentId));
  11.     }
  12.     set {
  13.         if (value == null) ParentId = null;
  14.         else ParentId = value.Id;
  15.     }
  16. }
  17.  
  18. partial void OnParentIdChanged() {
  19.     _parent = null;
  20. }

Пользовательский интерфейс будет состоять из одной формы и иконки в панели уведомлений. Форма будет отображаться и скрываться при клике на иконку, и обеспечивать простейший поиск нужного сотрудника по фамилии, и отображение информации по выбранному сотруднику.

Исходный код примера можно скачать здесь. Вкратце после инициализации привязок, в конструкторе формы, пытаемся считать данные из локальной БД, вызвав метод RefreshDataSource()
Copy Source | Copy HTML
  1. private void RefreshDataSource() {
  2.     if (_entityes == null) _entityes = PhoneRefEntities.Instance;
  3.     //Нужно для того чтобы возвратились данные из локальной БД, а не из кэша
  4.     _entityes.Refresh(System.Data.Objects.RefreshMode.StoreWins, _entityes.Stuff);
  5.     _bs.DataSource = (from stuff in _entityes.Stuff
  6.                       orderby stuff.LastName
  7.                       select stuff).ToList();
  8. }
  9.  
Если локальная БД еще ни разу не синхронизировалась с сервером, то возникнет исключение EntityCommandExecutionException. В этом случае пытаемся провести синхронизацию, и еще раз перечитать данные.
Copy Source | Copy HTML
  1. private void SynchronizeAndRefresh() {
  2.     try {
  3.         Data.Synchronization.SyncHelper.Synchronize();
  4.         RefreshDataSource();
  5.     } catch (Exception e) {
  6.         Trace.WriteLine(e);
  7.     }
  8.  
Ну и в дальнейшем настраиваем таймер таким образом что бы каждую минуту вызывался метод SynchronizeAndRefresh(). Теперь если изменить данные на сервере, то в течение минуты (разумеется при наличии связи с сервером) эти изменения окажутся на клиенте.
Итого первая цель достигнута. А именно у нас есть работающее приложение способное работать в offline-режиме, и умеющее автоматически синхронизировать локальную БД с сервером, при наличии связи.

0 коммент.:

Отправить комментарий