Version

Mapping Fields in Your Backend Data Source

A common scenario in providing the xamScheduleDataManager with data is that the scheduling data is stored in a database or in custom objects. The ListScheduleDataConnector exposes several ItemsSource properties (e.g., AppointmentItemsSource) that can be set to any IEnumerable object that will provide the schedule data for that collection. The ListScheduleDataConnector makes use of LINQ to query the data source. If the data source is IQueryable then LINQ is used to retrieve only the activities needed for the current display.

In order to map the properties from the data source objects to the xamSchedule entities that will be created, the associated PropertyMappings collection should be provided (e.g., AppointmentPropertyMappings). These are collections of PropertyMapping objects (e.g., AppointmentPropertyMapping) that specify the name of the property on the data source object (via the DataObjectProperty), the name of the xamSchedule entity property that it corresponds to (e.g., using the AppointmentProperty), and optionally a Converter that can be used to convert between the datasource object’s property value and the xamSchedule property value. The following is an example of using these mapping properties:

Note: Property mapping collection has a UseDefaultMappings property. If the names of the properties of the data source object are the same as the names of the properties of the xamSchedule entity object, this property can be set to true to automatically map the properties. Reflection is used to find properties with the same names and any matching properties are automatically mapped. Furthermore, if the names of some properties are not the same, explicit property mapping entries for those properties can be added to the collection.

In XAML:

<ig:ListScheduleDataConnector x:Name="scheduleDataConnector"
            ResourceItemsSource="{Binding CustomResources}"
            ResourceCalendarItemsSource="{Binding CustomCalendars}"
            AppointmentItemsSource="{Binding CustomAppointments}">
<ig:ListScheduleDataConnector.ResourcePropertyMappings>
        <ig:ResourcePropertyMappingCollection>
               <ig:ResourcePropertyMapping ResourceProperty="Id"
                        DataObjectProperty="MyId" />
                <ig:ResourcePropertyMapping ResourceProperty="Name"
                        DataObjectProperty="MyName" />
        </ig:ResourcePropertyMappingCollection>
    </ig:ListScheduleDataConnector.ResourcePropertyMappings>
<ig:ListScheduleDataConnector.ResourceCalendarPropertyMappings>
        <ig:ResourceCalendarPropertyMappingCollection>
                <ig:ResourceCalendarPropertyMapping
                        ResourceCalendarProperty="Id"
                        DataObjectProperty="MyId" />
                <ig:ResourceCalendarPropertyMapping
                        ResourceCalendarProperty="Name"
                        DataObjectProperty="MyName" />
                <ig:ResourceCalendarPropertyMapping
                        ResourceCalendarProperty="OwningResourceId"
                        DataObjectProperty="MyResourceId" />
        </ig:ResourceCalendarPropertyMappingCollection>
    </ig:ListScheduleDataConnector.ResourceCalendarPropertyMappings>
<ig:ListScheduleDataConnector.AppointmentPropertyMappings>
        <ig:AppointmentPropertyMappingCollection>
                <ig:AppointmentPropertyMapping
                        AppointmentProperty="Id"
                        DataObjectProperty="MyId" />
                <ig:AppointmentPropertyMapping
                        AppointmentProperty="Start"
                        DataObjectProperty="MyStart" />
                <ig:AppointmentPropertyMapping
                        AppointmentProperty="End"
                        DataObjectProperty="MyEnd" />
                <ig:AppointmentPropertyMapping
                        AppointmentProperty="OwningResourceId"
                        DataObjectProperty="MyOwnerId" />
                <ig:AppointmentPropertyMapping
                        AppointmentProperty="OwningCalendarId"
                        DataObjectProperty="MyCalendarId" />
                <ig:AppointmentPropertyMapping
                        AppointmentProperty="Subject"
                        DataObjectProperty="MySubject" />
                <ig:AppointmentPropertyMapping
                        AppointmentProperty="Description"
                        DataObjectProperty="MyDescription" />
        </ig:AppointmentPropertyMappingCollection>
    </ig:ListScheduleDataConnector.AppointmentPropertyMappings>
</ig:ListScheduleDataConnector>

In Visual Basic:

dataConnector.ResourcePropertyMappings =_
    New ResourcePropertyMappingCollection()
dataConnector.ResourcePropertyMappings._
    Add(ResourceProperty.Id, "MyId")
dataConnector.ResourcePropertyMappings._
    Add(ResourceProperty.Name, "MyName")
dataConnector.ResourceCalendarPropertyMappings =_
    New ResourceCalendarPropertyMappingCollection()
dataConnector.ResourceCalendarPropertyMappings._
    Add(ResourceCalendarProperty.Id, "MyId")
dataConnector.ResourceCalendarPropertyMappings._
    Add(ResourceCalendarProperty.Name, "MyName")
dataConnector.ResourceCalendarPropertyMappings._
    Add(ResourceCalendarProperty.OwningResourceId, "MyResourceId")
dataConnector.AppointmentPropertyMappings =_
    New AppointmentPropertyMappingCollection()
dataConnector.AppointmentPropertyMappings._
    Add(AppointmentProperty.Id, "MyId")
dataConnector.AppointmentPropertyMappings._
    Add(AppointmentProperty.Start, "MyStart")
dataConnector.AppointmentPropertyMappings._
    Add(AppointmentProperty.[End], "MyEnd")
dataConnector.AppointmentPropertyMappings._
    Add(AppointmentProperty.OwningResourceId, "MyOwnerId")
dataConnector.AppointmentPropertyMappings._
    Add(AppointmentProperty.OwningCalendarId, "MyCalendarId")
dataConnector.AppointmentPropertyMappings._
    Add(AppointmentProperty.Subject, "MySubject")
dataConnector.AppointmentPropertyMappings._
    Add(AppointmentProperty.Description, "MyDescription")

In C#:

dataConnector.ResourcePropertyMappings =
    new ResourcePropertyMappingCollection();
dataConnector.ResourcePropertyMappings.Add(
    ResourceProperty.Id, "MyId");
dataConnector.ResourcePropertyMappings.Add(
    ResourceProperty.Name, "MyName");
dataConnector.ResourceCalendarPropertyMappings =
    new ResourceCalendarPropertyMappingCollection();
dataConnector.ResourceCalendarPropertyMappings.Add(
    ResourceCalendarProperty.Id, "MyId");
dataConnector.ResourceCalendarPropertyMappings.Add(
    ResourceCalendarProperty.Name, "MyName");
dataConnector.ResourceCalendarPropertyMappings.Add(
    ResourceCalendarProperty.OwningResourceId, "MyResourceId");
dataConnector.AppointmentPropertyMappings =
    new AppointmentPropertyMappingCollection();
dataConnector.AppointmentPropertyMappings.Add(
    AppointmentProperty.Id, "MyId");
dataConnector.AppointmentPropertyMappings.Add(
    AppointmentProperty.Start, "MyStart");
dataConnector.AppointmentPropertyMappings.Add(
    AppointmentProperty.End, "MyEnd");
dataConnector.AppointmentPropertyMappings.Add(
    AppointmentProperty.OwningResourceId, "MyOwnerId");
dataConnector.AppointmentPropertyMappings.Add(
    AppointmentProperty.OwningCalendarId, "MyCalendarId");
dataConnector.AppointmentPropertyMappings.Add(
    AppointmentProperty.Subject, "MySubject");
dataConnector.AppointmentPropertyMappings.Add(
    AppointmentProperty.Description, "MyDescription");

In the sample code above the custom collections (CustomResources, CustomCalendars and CustomAppointments) are IEnumerable, and MyId, MyName, etc. are the names of the properties of the custom types that these collections contain.

Certain property mappings are required for proper functioning of the XamSchedule. Id field is one of them; and furthermore, the Id values have to be unique to each object in an items source.

Required Fields:

  • Id - String - Id values are not created and stored by the schedule data connector and therefore has not restrictions on what values it contains and what their lengths are as long as they are unique.

  • Id - String - Id values are not created and stored by the schedule data connector and therefore has not restrictions on what values it contains and what their lengths are as long as they are unique.

  • OwningResourceId - String - Values from the Resource’s Id field are used to link the resource calendar to a resource and therefore allowable length should correspond to the allowable length of the Resource’s Id field.

Common to Appointment, Journal and Task:

  • Id - String - For non-variance activities, by default GUID values are stored as strings and threfore should allow at least 36 characters. For variance activities, by default GUID plus a recurrence version plus a date-time value is stored which requires at least 60 characters.

  • Start - DateTime - This field can be a nullable DateTime field.

  • End - DateTime - This field can be a nullable DateTime field.

  • OwningResourceId - String - Values from the Resource’s Id field are used to link the resource calendar to a resource and therefore allowable length should correspond to the allowable length of the Resource’s Id field.

  • StartTimeZoneId - String - Should allow upto 40 characters.

  • EndTimeZoneId - String - Same as StartTimeZoneId.

The following fields are only required if ResourceCalendarItemsSource is provided:

  • OwningCalendarId - String - Values from the ResourceCalendar’s Id field are used to link the resource calendar to an activity and therefore allowable length should correspond to the allowable length of the ResourceCalendar’s Id field.

To support time-zone neutral activities:

To support recurring activities:

  • Recurrence - String - Recurrence rules are stored in iCalendar RECUR value format. This field should be variable length field that can have text values anywhere from approximately 30 characters to well over 100 characters.

  • MaxOccurrenceDateTime - DateTime - This field can be a nullable DateTime field.

To support variance of recurring activities:

To support reminders:

  • ReminderEnabled – Boolean

  • ReminderInterval – TimeSpan

  • Reminder – String – This field is not required for non-recurring activities however it is required to support reminders for recurring activities. This field should be a variable length text field.

Optional Fields:

The following listing defines requirements for the fields that are optional. Note that even though these fields are optional, you may want to provide mappings for some of them for better scheduling functionality.

  • Name – String

  • EmailAddress – String

  • Description – String

  • FirstDayOfWeek – .NET Nullable DayOfWeek enum type or nullable integer type.

  • DaysOfWeek – String – This field should be variable length text field where the ScheduleDaysOfWeek object is serialized as XML.

  • DaySettingsOverrides – String – This field should be variable length text field DaySettingsOverridesCollection is serialized as XML.

  • IsVisible – Nullable Boolean

  • IsLocked – Boolean

  • UnmappedProperties – String – Values of fields for which mappings are not provided will be stored in this field as XML. This field should be variable length text field. UnmappedProperties allows you to avoid defining fields that are not required and still allow for those fields’ values to be stored in the data source.

  • Name – String

  • Description – String

  • BaseColor – String

  • IsVisible – Nullable Boolean

  • UnmappedProperties – String – see description for Resource’s UnmappedProperties above.

LINQ usage in the ListScheduleDataConnector:

LINQ is used to retrieve activities on demand. Fields on which LINQ queries are performed are required to be of certain types.

Using LINQ to SQL:

When using LINQ to SQL, please define the DateTime and TimeSpan columns in the sql table as the following.

  • DateTime fields – Date-time range for the datetime sql data type is smaller than the .NET DateTime data type. In Microsoft SQL 2008 version, there’s a new datetime2 data type which allows for greater date-time range that matches the .NET DateTime data type. Therefore datetime2 should be used for any date-time fields. In older versions of SQL server, nullable datetime should be used, which will allow default(DateTime) values to be stored as null.

  • ReminderInterval – This field is required to be a TimeSpan field. Since Microsoft SQL server does not have a built in time-span data type, you can use bigint data type. However in your LINQ to SQL schema, you must change the property type of the LINQ to SQL entity object to be .NET TimeSpan. LINQ to SQL has built-in logic to perform the necessary conversion between .NET TimeSpan type and the underlying SQL bigint type.