In the first article of this series, we did a very high-level overview of LightSwitch. We looked at what exactly LightSwitch is and what you could do with it. We also built a very simple implementation of the demo we are using for this series, the MoviePolis application. This application consists at this point just out of 1 single screen, based on 2 entities.
In this part, we’ll focus first more on data. We’ll take a look at what options we have when creating data and we’ll also take a look at what happens behind the scenes.
The code for the MoviePolis application (as it looks at the end of this part) can be downloaded here.
Data as the foundation for a LightSwitch application
In the first part of this series, I already mentioned that in a LightSwitch application, things start with and evolve around data. Proof thereof is the landing page of a new LightSwitch project in Visual Studio, as can be seen in the following screenshot. The text “Start with data” is calling us to either create a new table from scratch in LightSwitch itself or to connect to an external data source.
Types of data
A LightSwitch application can connect to two types of data: local/internal data and external data. With local data, we are pointing at the database (SQL Server Express) that’s used behind the scenes by LightSwitch. If we start creating entities, by default, these will be created in this database. The local database is entirely managed by LightSwitch, which means that it can create entities but also do things such as managing the relations between entities.
An external data source points to all data that’s not the internal database. In other words, if we have LightSwitch connect to a SQL Server database, a SharePoint list or a WCF RIA Service, we are connecting to such an external data source. LightSwitch can manage the data of the external data source (it can perform CRUD operations for example); however it can’t manage the schema, create or delete relations etc.
The fact that we can connect to a WCF RIA Service is important. Since WCF RIA Services is DAL (Data Access Layer) neutral, it can basically connect with each type of DAL. Out-of-the-box, it supports Entity Framework and Linq-To-SQL, but it can perfectly work together with nHibernate if should be needed. Because of this, a LightSwitch application is not affected by the behind-lying database; the service layer forms an abstraction.
Although LightSwitch can’t change relations in an external source, it can create relations between an internal and an external source. What it does, it’s adding a foreign key in the internal table so it can keep track of the relation. Note also that one single LightSwitch application is capable of connecting with one internal and multiple external data sources at the same time. However, transactions on this aren’t supported.
The entity designer
The entity designer is really where it all starts. As the word says, we are creating the entities we will use in our applications here. The designer is really simple: it allows us to give the entity a name and add fields. Each field has a name, a type and a Boolean value indicating whether the field is required. The entity designer is shown next.
Both the entity and the fields have extended properties, which are displayed in the Properties window (it thus depends whether you have the entity selected or a field!). For the entity, we can specify the plural name, the name as it will be displayed and a summary property (we’ll look at this a bit further).
When we select a field, the following is shown in the Properties window. However, what is shown is dependent on the type we selected (String, Boolean…). Some properties, such as Maximum Length, are useful for validation purposes.
Let’s take a look at the available types…
Business types
When looking at the available types in the dropdown in the entity designer, we can see that there are some unusual types in there, including Money, Email Address and Phone Number. These are so-called Business Types. Such a type adds an extra layer on top of a normal database type. For example, the Email Address business type adds automatic validation for the entered value, as well as the ability to add a default domain to a string (so it becomes a valid email). Below is a screenshot showing the Properties window for the Email Address type.
When we run the application and we enter an invalid email, we’ll get feedback on this error without having to write any code for this.
When using the Phone Number type, at run-time, a specific window is shown to guide the user in entering a valid phone number, as shown below.
Business types are an extension point of LightSwitch, meaning that we can write our own. We’ll look at extensibility further in this series.
Summary properties and Computed properties
Let’s take another look at our current data model. We have movies and distributors. There’s a relation between these 2 entities. Let’s add another screen for the Movies, in this case an Editable Grid screen. Using this screen, we can add Movies, as shown below.
Note in the dialog that the Distributor drop-down is filled with a list of available Distributors. If we want to display an entity as a single line of text (which is done automatically for us here), we use a Summary Property. If none is defined for an entity, LightSwitch takes the first string property of the entity. However, assume that I’d like to show the contact name of the distributor here. In this case, we can change the property in the properties of the entity, as shown in the next image.
But wait, what happens if we want to make a combination, for example <DistributorName> (<ContactName > <ContactFirstName>)? In this case, we need to write some code and use what is called a computer property. Let’s add one by clicking on the Computed Property button in the designer. A new property is added, let’s call it FullDistributorName. We can see it’s computed because of the small calculator in front of the line.
Now we need to add code for this property. In the Compute method of this field, we are going to create the value ourselves. In the properties for this method, click the Edit Method button.
We arrive in C# code in the Compute method. This method is called every time this value needs to be updated. We add the following code:
partial void FullDistributorName_Compute(ref string result)
{
// Set result to the desired field value
result = this.Name + " (" + this.ContactFirstName + " " + this.ContactName + ")";
}
Now change the Summary Property to be the FullDistributorName. When running the application now, we can see the new value being used to summarize a Distributor.
Choice lists
For some fields, the values a user can enter are limited. Think of Yes/No, Male/Female, Available/Not Available… In this case, LightSwitch offers a choice list. In the properties window, with a field selected in the designer, we can select Choice List and add the available values. Here, we are entering available genres for a movie:
When running the application, as expected, this is shown as a dropdown list where the user can select one of the available values.
Validation using code
When we were adding the Computed Property, we already looked at how LightSwitch allows adding code. While some basic validation can be covered with the properties window (think of the Maximum Length, the type of a field…), most validation and business rules require us to write custom code. Assume that we want to validate that an added movie isn’t longer than 200 minutes (who would want to see a movie longer than that?). This is logic we can enter via some code.
To do so, in the Entity Designer, we select the property (here Duration) and then under the Write code button, we select the Duration_Validate event. This event is triggered when the value of this field changes so that the code therein is triggered automatically. We don’t need to write any callers for this code; LightSwitch, in its generated code, contains partial method calls that will call this method. We can focus on writing the business logic instead.
In this event, we write the following code:
partial void Duration_Validate(EntityValidationResultsBuilder results)
{
// results.AddPropertyError("<Error-Message>");
if (Duration > 200)
results.AddPropertyError("A movie shouldn't be longer than 200 minutes!");
}
When we try adding a movie with a greater duration, we’ll see the error being displayed in the application immediately, as shown below.
In a later article, I’ll be doing a deeper dive in the validation options offered by LightSwitch.
Now that we have more knowledge on the data part, let’s take a look at how data relates to screens and queries.
Sorting and filtering data
Up until now, when we created a screen, the default query was used. Basically, this query retrieves all data (“Select * from TABLE”). When we want to change this, we can change the query that lies behind.
Assume that we want to by default in the EditableMoviesGrid, we want to see movies ordered by ReleaseYear and then by Title. To do so, we can in the screen, change the query by clicking on the Edit Query link.
This will open the query designer where we can add filtering, sorting and parameters. To achieve the required ordering, I’ve added two sort elements.
As can be seen, filtering is similar.
Now let us take a look at how we can integrate with an already existing database from this LightSwitch application.
Connecting to an existing SQL Server 2008 database
Assume for the sake of this application that MoviePolis has another system where they manage the rooms with. When defining Show Times, we of course need to use the available rooms to show a movie in. The rooms are available in another SQL Server database. In order not to duplicate that data, we’ll want to connect with it from our LightSwitch application. This way, if MoviePolis ever extends, they can add the new rooms from the other application and our LightSwitch application will have access to the updated data as well.
LightSwitch is capable of connecting with the external database and it can use the data in its tables. To do so, in the Solution Explorer, right-click on the Data Sources node and select Add Data Source. In the dialog that appears, select Database and connect to the external SQL Server Database.
The database appears in LightSwitch:
We can now create a relation between this external table and an internal one. Below is the entity designer with the ShowTime table open. I have created a relation between this entity and the Room entity, which is part of the external database.
This results in the following in the designer:
It’s clear that we can connect to and work with external data from LightSwitch. This way, LightSwitch lends itself to build applications that need to integrate with existing databases/applications.
As already mentioned, LightSwitch can also connect to SharePoint and to a WCF RIA Service for its data needs. We’ll have a deep look at working with WCF RIA Services near the end of this series. Remember for now that RIA Services can act as a gateway to other data layer/databases: they can be used as a pass-through for data.
Data behind the scenes
To finish off this part about data, I thought it would be interesting to see what’s happening behind the scenes, in other words, how LightSwitch is handling the data we are giving it and what is being generated.
At the very top level, a LightSwitch application has a DataWorkspace. Only one exists in our application. It keeps track of all the data sources we have in our application. In the case of the MoviePolis application, it contains 2 properties: one for the internal data source and one for the external database. The internal one is referred to as ApplicationData (the file-based database, located in the bin/data directory is also named ApplicationDataBase) and the external one is named <NameOfDatabase>Data (here MoviePolisRoomManagementData).
For the data sources, LightSwitch generates an entity set for each entity. We’ll thus have a Movies, Distributors… entity set in our sample. Note that these are the plural names. LightSwitch also generates query methods for each entity type in all of the available data sources. These are:<Entity Name>_Single and <Entity Name>_SingleOrDefault. Individual objects (instances that is) are represented as an EntityObject.
Summary
In this long article, we have looked at the specifics of data in a LightSwitch application. We’ve looked at the entity designer and how we can change properties for both the entity and its fields. We’ve covered summary properties and computed properties and wrote our first lines of code in a LightSwitch application to perform basic validation. Finally, we have created a connection to an external SQL Server database as well as created a relation to a table thereof.
In the next part, we’ll be looking at the specifics of screens for LightSwitch applications. Stay tuned!
About Gill Cleeren
Gill Cleeren is Microsoft Regional Director (www.theregion.com), Silverlight MVP (former ASP.NET MVP), INETA speaker bureau member and Silverlight Insider. He lives in Belgium where he works as .NET architect at Ordina. Passionate about .NET, he’s always playing with the newest bits. In his role as Regional Director, Gill has given many sessions, webcasts and trainings on new as well as existing technologies, such as Silverlight, ASP.NET and WPF at conferences including TechEd Berlin 2010, TechDays Belgium, DevDays NL, NDC Oslo Norway, SQL Server Saturday Switzerland, Spring Conference UK, Silverlight Roadshow in Sweden… He’s also the author of many articles in various developer magazines and for SilverlightShow.net. He organizes the yearly Community Day event in Belgium.
He also leads Visug (www.visug.be), the largest .NET user group in Belgium. Gill recently published his first book: “Silverlight 4 Data and Services Cookbook” (Packt Publishing). You can find his blog at www.snowball.be.
Twitter: @gillcleeren