Silverlight 4 Telerik Scheduler Issue

Telerik controls version 2010.1.422.1040

I recently took over a Silverlight Telerik scheduler which was having an issue with displaying appointments on a resource view.   The only way I could get appointments to display is if “DisplayEmptyGroup” property on the scheduler was set to true.  All the appointments were assigned to a resource, but would not display on the scheduler.

The issue was the assignment of the resources to appointments.  The appointments were loaded and added to the Telerik appointment collection.  Then each appointment in the collection was looped through and assigned to the resource.  So as the appointments were added to the collection, they defaulted to an empty resource group since it was not yet assigned to the resource.  For some reason, since the empty group is not displayed (“DisplayEmptyGroup”  set to false), the appointments did not show up on the scheduler when the resource was eventually assigned to the appointment.

To fix the problem, I assigned the resource to an appointment before adding it to the collection.  Problem solved!!!

LINQ Lazy Loading

I was experiencing some performance issues in my Silverlight application and got it narrowed down to the mapping of the domain objects.  After running SQL profiler and doing some research I figured out that it was due to Linq lazy loading.

As an example if I have the following data structure:

Employee_EmployeePosition

I would have an “EmployeePosition” domain object and an “Employee” domain object.  I will use the following Linq statement to bring back all Employee Positions:

  1. using (var dc = new DataClasses1DataContext())
  2. {
  3.     var postiions = dc.EmployeePositions.ToList();
  4. }

Linq lazy loading is enabled by default, so by executing the above query Linq will only bring back Employee Positions.  If I am only looking for Employee Positions everything works as expected.  The issue appears if I want to bring back the Employee information for each position.  Since I have a foreign key relationship between “Employee” and “EmployeePosition”, my dbml has “one to many” association between them.  This allows me to write the following mapping to my object that I return to my Silverlight application:
  1. var myEmployees = postiions.Select(x => new EmployeeWithPosition
  2.                     {
  3.                         FirstName = x.Employee.FirstName,
  4.                         LastName = x.Employee.LastName,
  5.                         Position = x.Position
  6.                     }).ToList();

When executing above code, there is a separate call made to the database to get the “FirstName” then another call to get the “LastName” for each of the “EmployeePosition” objects due to LINQ lazy loading (default).  So if I have 10 employee positions, there are 20 additional calls made to the database.

There are a few solutions to solve this issue:

    1. Disable lazy loading for the entire dbml file. 
    2. Specify “DataLoadOptions” on the Data Context.  This is a valid option if you do not re-use the Data Context.
    3. Use projection to load only necessary data.

The best option for my situation was to use projection to load my data.  To do this I extended my existing Employee domain object by creating a partial “Employee” class and adding a string “Position” property.  Then I used projection to load my data to the Employee domain object.

  1. using (var dc = new DataClasses1DataContext())
  2. {
  3.     var myEmployees = dc.EmployeePositions.Select(x => new Employee
  4.     {                    
  5.         FirstName = x.Employee.FirstName,
  6.         LastName = x.Employee.LastName,                    
  7.         Position = x.Position
  8.     }).ToList();
  9. }

When I executed above code I got the following run-time error:

Explicit construction of entity type ‘Employee’ in query is not allowed.

After doing a little research I discovered that projection to a domain object is not allowed. As a work around, I used my “EmployeeWithPosition” custom object which only contains properties that I am interested in from the “Employee” and “EmployeePosition” domain objects to project my data.

  1. using (var dc = new DataClasses1DataContext())
  2.             {
  3.                 var myEmployees = dc.EmployeePositions.Select(x => new EmployeeWithPosition
  4.                 {                    
  5.                     FirstName = x.Employee.FirstName,
  6.                     LastName = x.Employee.LastName,                    
  7.                     Position = x.Position
  8.                 }).ToList();
  9.             }

Upgrading Silverlight 3 Project to Silverlight 4

Recently I upgraded our Silverlight 3 project with WCF services to Visual Studio 2010 Silverlight 4.  Overall the upgrade went smoothly with a few glitches.  Following are some basic steps:

  • Install Blend 4 (if using blend references)
  • Install Silverlight 4 toolkit
  • Run the Visual Studio conversion wizard
  • Update broken references
  • Change all Silverlight projects to target Silverlight 4 in the project properties
  • Delete all WCF references and re-add them
    • When adding a service reference, choose “Reuse types in referenced assemblies" and select specific assemblies instead of the "Always generate message contracts" option.

WCFConfigureService If attached to source control, you may need to name newly added references differently or re-name existing references before deleting.

After running the solution through the conversion wizard I was getting several errors with the WCF services.  I tried removing and re-adding the services several times with the “Always generate message contracts” option selected, which worked fine with Silverlight 3 in Visual Studio 2008.  By selecting the option to reuse types and checking the specified assemblies, I was able to resolve my issue with WCF in Visual Studio 2010.