Демо V. Сервер Oracle   

   

Демо V. Сервер Oracle

 Как вы заметили, мы постоянно экспериментируем с SQL Server в качестве серверной части наших примеров. Теперь вы можете спросить: что если база данных не SQL Server? Должен ли я писать страницы кода, чтобы достичь той же функциональности? В конце концов, это технология Майкрософт и кто тут позаботится о другом типе сервера?

Ну, на самом деле все не так, и серверы синхронизации были разработаны с поддержкой различных видов серверов. Если вы ближе познакомитесь с интерфейсом, вы заметите, что класс провайдера сервера назван DbServerSyncProvider (а не SqlServerSyncProivder), что означает возможность использования любой базы данных, а не только SQL Server. Пока вы используете провайдер ADO.NET для любой базы данных, вы можете пользоваться преимуществами Sync Services.

В этом примере я изменю оффлайн-приложение для работы с Oracle. Для того чтобы не терять главную идею и чтобы упростить код, я реализую только сценарий «download» для таблицы ‘orders’. Однако, вы можете реализовать другие возможности сервисов синхронизации с Oracle с теми же простотой и контролем.

ADO.NET имеет специальный провайдер доступа для баз данных Oracle, который я и буду использовать в своей программе. Вы можете также использовать провайдеры OLEDB или ODBC по вашему усмотрению.

Нижеприведенный рисунок демонстрирует основную форму приложения. Заметьте, что я добавил новое текстовое поле для сроки соединения, чтобы можно было легко связываться с базой Oracle. Я также добавил две кнопки внизу формы для добавления и удаления таблицы 'orders'. Кнопки случайного добавления, обновления и удаления тоже присутствуют как ярлыки для упрощения манипуляций содержимым базы данных Oracle. Так как программа демонстрирует только сценарий download, эти кнопки будут деактивированы в режиме клиентского просмотра.


Как показано ниже, код для SyncAdapter довольно прост. Мне было необходимо только определить команды для добавления инкрементных вставок, обновлений и удалений, и этого хватило для реализации сценария download:

// orders table
SyncAdapter adaptorOrders = new SyncAdapter("orders");               

// select incremental inserts command
OracleCommand incInsOrdersCmd = new OracleCommand();
incInsOrdersCmd.CommandType = CommandType.Text;
incInsOrdersCmd.CommandText = "SELECT id, col2, col3, col4 FROM orders " +   
                              "WHERE track_insert is null OR (  track_insert > :" +
                              SyncSession.SyncLastReceivedAnchor + " " +
                              "and track_insert <= :" + SyncSession.SyncNewReceivedAnchor + " )";

incInsOrdersCmd.Parameters.Add(":" + SyncSession.SyncLastReceivedAnchor, OracleType.Timestamp);
incInsOrdersCmd.Parameters.Add(":" + SyncSession.SyncNewReceivedAnchor, OracleType.Timestamp;    adaptorOrders.SelectIncrementalInsertsCommand = incInsOrdersCmd;

// select incremental updates command
OracleCommand incUpdOrdersCmd = (OracleCommand)incInsOrdersCmd.Clone();                incUpdOrdersCmd.CommandText = "SELECT id, col2, col3, col4 FROM orders " +                                      "WHERE (track_update > :"+SyncSession.SyncLastReceivedAnchor+") " +
                              "and (track_update <= :"+SyncSession.SyncNewReceivedAnchor+") " +
                              "and (track_insert <= :"+SyncSession.SyncLastReceivedAnchor+") ";
incUpdOrdersCmd.Parameters.Add(":" + SyncSession.SyncLastReceivedAnchor, OracleType.Timestamp);
incUpdOrdersCmd.Parameters.Add(":" + SyncSession.SyncNewReceivedAnchor, OracleType.Timestamp);
adaptorOrders.SelectIncrementalUpdatesCommand = incUpdOrdersCmd;

serverSyncProvider.SyncAdapters.Add(adaptorOrders);            

Если и есть что-то, что можно было бы выделить в этой демонстрации помимо возможности использовать SyncServerProvider для различных серверных частей, так это преобразование времени между сервером и клиентом. База данных Oracle имеет отличный формат от SqlCe, который используется на клиенте для создания таблицы orders. Чтобы это исправить, мне пришлось отказаться от автоматической схемы, которую предоставляет сервер, и создать в провайдере объект SyncSchema, содержащий всю информацию по преобразованию. Ниже показано как я это делаю для первых 3-х колонок:

//
// 5. Custom Schema
//

SyncSchema syncSchema = new SyncSchema();
serverSyncProvider.Schema = syncSchema;

syncSchema.Tables.Add("orders");

syncSchema.Tables["orders"].Columns.Add("id");
syncSchema.Tables["orders"].Columns["id"].AllowNull = false;
syncSchema.Tables["orders"].Columns["id"].ProviderDataType = "NUMERIC";
syncSchema.Tables["orders"].Columns["id"].NumericPrecision = 5;
syncSchema.Tables["orders"].Columns["id"].NumericScale = 0;
syncSchema.Tables["orders"].PrimaryKey = new string[] { "id" }; 

syncSchema.Tables["orders"].Columns.Add("col2");
syncSchema.Tables["orders"].Columns["col2"].ProviderDataType = "CHAR";
syncSchema.Tables["orders"].Columns["col2"].MaxLength = 40; 

syncSchema.Tables["orders"].Columns.Add("col3");
syncSchema.Tables["orders"].Columns["col3"].DataType = typeof(String);
syncSchema.Tables["orders"].Columns["col3"].MaxLength = 32;

syncSchema.Tables["orders"].Columns.Add("col4");
syncSchema.Tables["orders"].Columns["col4"].ProviderDataType = "NUMERIC";
syncSchema.Tables["orders"].Columns["col4"].NumericPrecision = 38;
syncSchema.Tables["orders"].Columns["col4"].NumericScale = 0;

Остальные колонки могут быть преобразованы так же.

Если вы проанализируете автоматическую схему, генерирующуюся провайдером, то заметите, что значения NumericPrecision и NumericScale не установлены. Вот почему клиент не может их использовать. Возможность авторизовать схему и передать ее на провайдер сервера дает вам возможность контролировать как таблицы устанавливаются на клиенте безотносительно серверной части базы данных. Это очень мощная возможность, которая позволит вам строить свои серверные провайдеры для серверных частей, отличных от баз данных.

Наслаждайтесь!

Шаги инсталляции приложения OfflineAppDemo:

  • Загрузите Oracle 10g express, если у вас нет сервера Oracle для тестирования: http://www.oracle.com/technology/software/products/database/xe/htdocs/102xewinsoft.html
  • Загрузите решение VS (OfflineAppDemo-Builder Project)
  • Скомпилируйте проект
  • Запустите приложение
  • Заполните строку соединения на основной форме
  • Используйте UI для создания серверной базы данных и заполните ее перед синхронизацией