Migration Guide: Moving ExpressScheduler Data to XtraScheduler Smoothly

Complete Migration: Transforming ExpressScheduler Data for XtraScheduler Integration

Overview

This guide outlines a complete migration path for moving scheduling data stored for DevExpress ExpressScheduler into DevExpress XtraScheduler. It covers data model mapping, export/import strategies, code samples, common pitfalls, and validation steps to ensure appointments, resources, recurrence rules, and custom metadata transfer accurately.

Key Steps

  1. Assess source data

    • Inventory appointments, resources, categories, custom fields, recurrence patterns, and any storage format (DataTable, XML, database schema).
    • Note timezone usage and any custom serialization.
  2. Map data models

    • Match ExpressScheduler fields to XtraScheduler equivalents:
      • Appointment subject → Appointment.Subject
      • Start/End → Appointment.Start, Appointment.End
      • AllDay → Appointment.AllDay
      • Description → Appointment.Description
      • Location → Appointment.Location
      • Resource IDs → Appointment.ResourceId (or use ResourceMapping)
      • Recurrence rules: convert from any custom format to iCalendar RRULE or XtraScheduler recurrence pattern
      • Custom fields → Appointment.CustomFields or a linked table
  3. Choose migration strategy

    • Direct database migration: write SQL to transform and insert into XtraScheduler tables.
    • Export/import via intermediary format: serialize ExpressScheduler data to JSON/XML/iCal, then parse into XtraScheduler.
    • In-app migration: run a migration routine within the application that reads from old storage and creates XtraScheduler appointments programmatically.
  4. Implement conversion logic

    • Use XtraScheduler API to create appointments and resources. Example (C#):

      csharp

      Appointment apt = scheduler.Storage.CreateAppointment(AppointmentType.Normal); apt.Subject = old.Subject; apt.Start = old.Start; apt.End = old.End; apt.AllDay = old.AllDay; apt.Description = old.Description; apt.Location = old.Location; apt.ResourceId = MapResource(old.ResourceId); // handle recurrence if(old.IsRecurring) { apt.RecurrenceInfo = ConvertRecurrence(old.RecurrenceData); } scheduler.Storage.Appointments.Add(apt);
    • For bulk imports, wrap operations in transactions and suspend UI updates for performance.
  5. Handle recurrence and exceptions

    • Convert recurring definitions to RecurrenceInfo; translate exception dates and modified occurrences individually.
    • If source uses iCalendar, XtraScheduler can import RRULEs—map any unsupported properties manually.
  6. Migrate resources and categories

    • Create Resource objects in XtraScheduler’s ResourceStorage with consistent IDs.
    • Map categories/colors to Appointment.Label or custom fields.
  7. Preserve timezones

    • Normalize timestamps to UTC where possible and set appropriate TimeZoneId on appointments if supported; ensure consistent display.
  8. Transfer custom metadata

    • Use Appointment.CustomFields or a side table keyed by appointment ID for application-specific data.
  9. Validation and testing

    • Compare counts, sample appointments, recurrence behavior, resource assignments, and UI rendering.
    • Run automated tests for edge cases: overlapping events, long-running events, daylight saving transitions.
  10. Rollback and backup

    • Backup original data before migration.
    • Provide a rollback plan or keep an archived copy of original data.

Common Pitfalls

  • Loss of recurrence exceptions when naively converting RRULEs.
  • Mismatched resource IDs causing appointments to appear unassigned.
  • Timezone shifts leading to incorrect start/end times.
  • Performance issues when inserting large volumes without batching.

Post-migration Tasks

  • Re-index any database tables for performance.
  • Reapply permissions and sharing settings if they were stored separately.
  • Update documentation and inform users of any small behavioral differences.

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *