Apr 18

Written by: Michael Washington
4/18/2012 9:37 PM  RssIcon

image

The LightSwitch Silverlight screens allow you to easily group and total data. The LightSwitch OData services return one Entity collection at a time. This makes grouping and totaling across Entity collections difficult. Using WCF RIA Services provides a clean elegant solution.

image

In the Flower Shop application used in the tutorial: Calling LightSwitch 2011 OData Using Server Side Code we have two computed fields in the FlowerShopOrder Entity.

image

These fields allow us to easily display the Order Total and the name of the Customer.

image

However, if we connect to the OData service for that Entity, we see it does not contain the Order Total nor the name of the Customer.

To get this data, it requires additional queries of Customer Entity to get the Customer name, the Product Entity to get the Product price, and all the related Order Detail Entities to calculate the Order Total.

This is a problem because not only does it require additional database queries, it requires the client consuming the OData feed to now be responsible for complex business logic.

We can create an OData service with these computed fields using a WCF RIA Service.

Create A WCF RIA Service

image

Open up the Flower Shop application used in the tutorial: Calling LightSwitch 2011 OData Using Server Side Code and Add a New Project.

image

Create a Class Library called WCF_RIA_Project.

image

Delete the Class1.cs file that is automatically created.

image

Add a New Item to WCF_RIA_Project.

image

Add a Domain Service Class called WCF_RIA_Service.

image

When the Add New Domain Service Class box comes up, uncheck Enable client access. Click OK.

This domain class will be exposed by LightSwitch and will pass through its security and business rules.

image

We need additional references, add the following references to the WCF_RIA_Project

image

 

  • System.ComponentModel.DataAnnotations
  • System.Configuration
  • System.Data.Entity
  • System.Runtime.Serialization
  • System.ServiceModel.DomainServices.Server (Look in %ProgramFiles%\Microsoft SDKs\RIA Services\v1.0\Libraries\Server)
  • System.Web

 

Add the following Using Statements to the class:

image

using ApplicationData.Implementation;
using System.Data.EntityClient;
using System.Web.Configuration;

(ApplicationData will display a squiggly red line because the class is missing, but it will be added in a subsequent step)

 

Reference The LightSwitch Object Context

Now, we will add code from the LightSwitch project to our WCF RIA Service project. We will add a class that LightSwitch automatically creates, that connects to the database that LightSwitch uses.

We will use this class in our WCF RIA Service to communicate with the LightSwitch database.

 

image

Right-click on the WCF_RIA_Project and select Add then Existing Item.

image

Navigate to ..Server\GeneratedArtifacts (in the LightSwitch project)and click on ApplicationData.cs and Add As Link.

We used “add As Link” so that whenever LightSwitch updates this class, our WCF RIA Service is also updated. This is how our WCF RIA Service would be able to see any new Entities (tables) that were added, deleted, or changed.

Create the Domain Service

We use the following code for the WCF RIA Service:

 

namespace WCF_RIA_Project
{
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.ComponentModel.DataAnnotations;
    using System.Linq;
    using System.ServiceModel.DomainServices.Hosting;
    using System.ServiceModel.DomainServices.Server;
    using ApplicationData.Implementation;
    using System.Data.EntityClient;
    using System.Web.Configuration;
    // This class is used as the class that is returned
    // This can have any 'shape' you desire
    // Make sure this is outside of the WCF_RIA_Service class
    // but inside the WCF_RIA_Project namespace
    public class EnhancedFlowerShopOrder
    {
        [Key]
        public int ID { get; set; }
        public DateTime OrderDate { get; set; }
        public string FirstName { get; set; }
        public string LastName { get; set; }
        public decimal OrderTotal { get; set; }
    }
    public class WCF_RIA_Service : DomainService
    {
        // This Context property is code that connects to the LightSwitch database
        // The code in the Database connection region can be reused as it is 
        #region Database connection
        private ApplicationDataObjectContext m_context;
        public ApplicationDataObjectContext Context
        {
            get
            {
                if (this.m_context == null)
                {
                    string connString =
                        System.Web.Configuration.WebConfigurationManager
                        .ConnectionStrings["_IntrinsicData"].ConnectionString;
                    EntityConnectionStringBuilder builder = new EntityConnectionStringBuilder();
                    builder.Metadata =
                        "res://*/ApplicationData.csdl|res://*/ApplicationData.ssdl|res://*/ApplicationData.msl";
                    builder.Provider =
                        "System.Data.SqlClient";
                    builder.ProviderConnectionString = connString;
                    this.m_context = new ApplicationDataObjectContext(builder.ConnectionString);
                }
                return this.m_context;
            }
        }
        #endregion
        [Query(IsDefault = true)]
        public IQueryable<EnhancedFlowerShopOrder> GetAllOrders()
        {
            // Get all the Orders
            var colFlowerShopOrders = from Order in this.Context.FlowerShopOrders
                                      // Shape the results into the 
                                      // EnhancedFlowerShopOrder class
                                      select new EnhancedFlowerShopOrder
                                      {
                                          // The Order ID
                                          ID = Order.Id,
                                          // The Order Date
                                          OrderDate = Order.OrderDate,
                                          // The first name of the Customer
                                          FirstName = Order.FlowerShopCustomer.FirstName,
                                          // The last name of the Customer
                                          LastName = Order.FlowerShopCustomer.LastName,
                                          // The order Total
                                          OrderTotal =
                                          // Get all order details lines of the Order
                                          (from FlowerShopOrderDetail in Order.FlowerShopOrderDetail
                                           // Group the products in the Order Details
                                           group FlowerShopOrderDetail 
                                           by FlowerShopOrderDetail.FlowerShopProduct into g
                                           // Shape a new entity
                                           select new
                                           {
                                               // Create a total property that is the Quantity times the
                                               // Product price
                                               TotalOrder = g.Sum(x => x.Quantity) 
                                               * g.Sum(x => x.FlowerShopProduct.Price),
                                           }).Sum(x => x.TotalOrder) // Add the sum of all the TotalOrders
                                      };
            return colFlowerShopOrders;
        }
        // Override the Count method in order for paging to work correctly
        protected override int Count<T>(IQueryable<T> query)
        {
            return query.Count();
        }
    }
}

 

Consume The WCF RIA Service

image

Build the solution.

(You will get a ton or warnings in the immediate window, you can ignore them)

image

In the Solution Explorer (of the LightSwitch project), right-click on the Data Sources folder and select Add Data Source.

image

Select WCF RIA Service.

image

Click Add Reference.

image

Click Browse…

image

Navigate to the WCF_RIA_Project.dll in FlowerShop/WCF_RIA_Project/bin/debug and select it.

image

It will display in the dialog box, select it and click OK.

image

Wait for the service to show up in the selection box, select it and click Next.

image

Check the box next to the Entities, and click Finish.

image

The Entity will display.

Display The Data

image

The WCF RIA Service will have its own node under Data Sources in the LightSwitch project.

That name plus “.svc” is used to navigate to the OData service.

image

We can now issue a simple query to access the data.

An Important Note About SSL

A production application must run on a webserver that has SSL enabled. Otherwise, a hacker with a packet sniffer can easily get the data and the usernames and passwords of your users who are connecting to your site using public Wi-Fi access points or other unsecure networks.

Also See

A Full CRUD DataJs and KnockoutJs LightSwitch Example Using Only An .Html Page

A Full CRUD LightSwitch JQuery Mobile Application

Calling LightSwitch 2011 OData Using Server Side Code

Using The OData Explorer with LightSwitch OData

Learn How To Make OData Calls In LightSwitch 2011

Accessing Your Visual Studio 2011 LightSwitch Application Using OData

Download Code

The LightSwitch project is available at:

http://lightswitchhelpwebsite.com/Downloads.aspx

Tags: OData
Categories:

9 comment(s) so far...


Gravatar

Re: Shape Your LightSwitch OData Using WCF RIA Services

This is a wonderful article to get started with WCF RIA Services in lightswitch.
Is it possible to get the routine:
public IQueryable GetAllOrders()
where the order is grouped by Order Date?
Thanks so much for your contribution.
Rachida

By Rachida on   7/9/2012 10:16 AM
Gravatar

Re: Shape Your LightSwitch OData Using WCF RIA Services

@Rachida - Yes it is. Just change the Linq Query. Any site that describes grouping using Linq will be able to help you work out what you need.

By Michael Washington on   7/9/2012 12:38 PM
Gravatar

Re: Shape Your LightSwitch OData Using WCF RIA Services

Thanks so much Michael for your fast response. Can you recommend any blog or book to learn RIA service for lightswitch.
I added a seond routine like IQueryable GetAllOrders() with a different name, and rebuilt the whole solution but I got to the window called ( attach data source wizard), I can see only one entity EnhancedFlowerShopOrder, but NEVER the added routine.
What I'm doing wrong?
Thanks again.
Rachida

By Rachida on   7/9/2012 2:57 PM
Gravatar

Re: Shape Your LightSwitch OData Using WCF RIA Services

@Rachida - I don;t have a book to reccomend, but ANY book or article on WCF RIA Services will work. The WCF RIA Services are not LightSwitch specific.

As to the second method you added, I think you have to make sure you do NOT decorate it with "[Query(IsDefault = true)]".

By Michael Washington on   7/9/2012 3:09 PM
Gravatar

Re: Shape Your LightSwitch OData Using WCF RIA Services

Thanks Michael again, Rachida

By Rachida on   7/9/2012 3:27 PM
Gravatar

Re: Shape Your LightSwitch OData Using WCF RIA Services

******** Note: With the latest version of Visual Studio LightSwitch HTML Client you need to connect to "ApplicationDataObjectContext.cs", change "ApplicationDataObjectContext" (in the code) to "ApplicationData" and use: "using LightSwitchApplication.Implementation;" in the using statement section. ********

By Michael Washington on   4/11/2013 10:26 PM
Gravatar

Re: Shape Your LightSwitch OData Using WCF RIA Services

How do add WCF RIA in VS 2013?
There is no possibility to add a Domain Service Class

By blakcat76 on   11/20/2013 2:49 AM
Gravatar

Re: Shape Your LightSwitch OData Using WCF RIA Services

@blakcat76: see: http://lightswitchhelpwebsite.com/Blog/tabid/61/tagid/21/WCF-RIA-Service.aspx

By Michael Washington on   11/20/2013 4:23 AM
Gravatar

Re: Shape Your LightSwitch OData Using WCF RIA Services

Thanks Michael Washington

By blakcat76 on   11/20/2013 6:44 AM

Your name:
Gravatar Preview
Your email:
(Optional) Email used only to show Gravatar.
Your website:
Title:
Comment:
Security Code
CAPTCHA image
Enter the code shown above in the box below
Add Comment   Cancel 
Microsoft Visual Studio is a registered trademark of Microsoft Corporation / LightSwitch is a registered trademark of Microsoft Corporation