CHAPTER 2

image

Setting Up Your Data

LightSwitch’s greatest strength is how easy it makes working with data. So to get the most out of the product, it’s vital that you learn how to do that!

This chapter teaches you how to

  • Design tables and attach external data sources to your application
  • Define relationships between tables
  • Create computed properties and apply business types

This chapter traces the genesis of an application that manages help desk issues. It provides a real-life demonstration of a typical application that you’ll find in everyday business, and includes sufficient complexity to demonstrate most of the features in LightSwitch.

In this chapter, you’ll find out how to create tables that store help desk issues and engineer details. You’ll learn how to associate engineers with multiple issues and how to define a manager/engineer hierarchy by defining relationships. To help users identify engineers in lists of data, you’ll learn how to create a computed property and define a summary property. The computed property summarizes the first name and surname of each engineer, and provides a friendly record descriptor for each engineer record.

Choosing Where to Store Your Data

There are two approaches for storing data in LightSwitch. You can create your own tables in the Intrinsic database by using the built-in table designer, or you can attach to an external data source. Of course, these two approaches are not mutually exclusive. You can create your own tables and also attach as many external data sources as you want.

When you build tables using the built-in table designer, LightSwitch persists any data that you add at design time. So if you add some data to a table during a debug session, your data will still be there during the next debug session. For this to work, LightSwitch creates a LocalDB development database in the location BinDataTempApplicationDatabase.mdf.

The advantage of creating tables in the Intrinsic database is that your project is self-contained. If you share your LightSwitch project with other users, they’ll be able to run your project without having to reattach the external data.

The difficulty arises when you deploy your application. The deployment wizard doesn’t allow you to deploy your development data into your live environment. This can be frustrating if you’ve spent a lot of time entering data during the design process. So if design time data is important to you, you should consider building your tables externally in a Microsoft SQL Server database rather than building it internally within LightSwitch.

What Are Entities and Properties?

Database developers often use the terms tables and rows. However, LightSwitch regularly refers to entities and properties instead. An entity represents the data from a single row in a database table, whereas a property is analogous to a field or column from a database table.

LightSwitch uses Microsoft’s Entity Framework internally to provide object relational mapping. Entity and Property are terms that the Entity Framework uses, and are more appropriate given that LightSwitch can connect to nonrelational data sources. For example, if you connect to a SharePoint data source, list items map to LightSwitch entities, and list columns are exposed as LightSwitch properties.

In this book, I use the words tables and fields interchangeably because it’s often clearer to use the database terms. For example, a property in the screen designer can mean a local instance of an entity or something that you can find in Visual Studio’s property sheet. And once you start talking about the properties of a property, things can quickly become quite confusing.

Creating Tables (Entities)

Let’s start by creating a new table and adding some fields. We’ll create a table called Engineers that stores details about the engineers.

In Solution Explorer, right-click the Data Sources folder and choose the Add Table option. Once you’ve added your table, you can modify the properties using the Properties sheet. (See Figure 2-1.)

9781430250715_Fig02-01.jpg

Figure 2-1. Creating a table and editing its properties

Some of the table properties that you can set include

  • Name: The name uniquely identifies your table. The name must begin with an alphabetic character and can contain only alphanumeric characters and the underscore character. Other special characters, such as spaces or the period character, are not permitted.
  • Display name: This is the friendly name that describes your table—it can contain spaces.
  • Description: The description field provides a long description of the table.
  • Plural Name: LightSwitch uses the value that you enter here to name the collections of entities that you add to a screen. You would also use the plural name to refer to collections of entities when you’re writing code.
  • Summary Property: this allows you to specify the property that identifies a data row to a user. You can add a control to your screen called a Summary Control that exposes the value of this property to the user.
  • Default Screen: The Summary Control renders itself as a link. When a user clicks on this link, it opens the default screen that’s specified here. There is an option to select Auto from the drop-down list. If you select Auto, LightSwitch displays an autogenerated screen.
  • Is Searchable: Checking this defines that the text properties in the table will be searchable.

Creating Fields (Properties)

After creating the Engineer table, add the fields (or properties) that are shown in Figure 2-1. When you add a field to a table, you’ll need to specify the type of data that’ll be stored in the field. Let’s take a look at some of the data types that you can use.

image Caution  Try not to name your fields using words that are reserved keywords in SQL Server or the Entity Framework. Prefixing field names with the word Entity (for example, EntityKey) caused unexpected errors in LightSwitch 2011. Although Microsoft has fixed this particular bug, it’s safer never to name your fields after reserved keywords because you never know what unexpected errors might occur.

Storing String Data

The string data type includes support for international character types (for example, Arabic, Chinese, and Japanese). For maximum performance, it’s a good idea to set the maximum field size to a value that’s appropriate for the data that you want to store.

If you want to store unlimited length or multiline text, clear the contents of the maximum field text box and leave it blank, as shown in Figure 2-2.

9781430250715_Fig02-02.jpg

Figure 2-2. Setting a string field to store text with unlimited length

Storing Numbers (Double and Decimal Types)

If you want to store numbers with decimal places, LightSwitch provides a choice of either double or decimal data types.

The practical difference between the two types is that doubles can store a wide range of numbers in a smaller amount of memory. However, doubles are less precise and are subject to rounding errors when calculations are performed against them.

Decimals don’t suffer from such rounding errors but take up more space and are slower to compute. Sums of money should always be based on the decimal data type.

Other important attributes that relate to decimals are precision and scale. Precision defines the total number of digits in a number. Scale defines the number of digits after the decimal place. Figure 2-3 illustrates precision and scale using the example number 123456.789.

9781430250715_Fig02-03.jpg

Figure 2-3. Precision and scale

When you create a new decimal field, LightSwitch defaults the precision and scale values to 18 and 2, respectively. In keeping with good practice, you should shorten these values if you don’t require that level of accuracy.

Formatting Numeric Fields

This is a new feature in LightSwitch 2012. You can specify a display format for each numeric property that you define in LightSwitch. This means that LightSwitch formats the number on the user’s screen using the format that you’ve specified.

Figure 2-4 shows a field that stores a feedback rating. A format string of N2 means that the number is shown to 2 decimal places.

9781430250715_Fig02-04.jpg

Figure 2-4. Setting the format

.NET format strings begin with a Format Specifier, followed by a number that indicates the desired number of decimal places. Table 2-1 shows the Format Specifiers that you can use.

Table 2-1. .NET format specifiers

Format Specifier Description
C or c Currency
D or d Decimal
E or e Scientific (exponential)
F or f Fixed-point
G or g General
N or n Number
P or p Percent
R or r Round-trip
X or x Hexadecimal

image Note  LightSwitch 2011 didn’t allow you to format numeric fields with .NET format strings. In March 2011, I submitted this idea on Microsoft Connect, a web site that allows you to provide feedback on how to improve Microsoft products: https://connect.microsoft.com/VisualStudio/feedback/details/654220/lightswitch-allow-data-to-be-formatted.

I’m very pleased that Microsoft has added this useful feature. This goes to show that if you have any ideas on how to improve LightSwitch, it’s worth recording them through Connect or the Uservoice web site (http://visualstudio.uservoice.com/).

Storing Images

The Image Type allows you to store images. LightSwitch includes Image Editor and Image Viewer controls that allows users to upload and view images.

Note that these controls support only images in JPG and PNG format. If you want to upload and view image files in other formats, you’ll need to write or purchase a third-party custom control.

Storing Binary Data

You can use the binary data type to store binary large objects such as documents, videos, or other file types. Chapters 7 and 8 show you how to design a screen that allows users to upload and download files.

Ensuring Unique Values

Each field contains an Include In Unique Index check box. Selecting this check box adds the field into a combination index.

It’s not possible to create individual unique fields through the designer. If you want to do this, you can write validation to enforce uniqueness at a field level. Chapter 5 contains sample code that shows you how to do this.

Alternatively, you could create unique indexes on your SQL Server table if you’re using an attached SQL database.

Changing Data Types

If you’re working on tables in your Intrinsic database and make some major table changes, LightSwitch can discard the data in your tables. At worst, it can even destroy and re-create your entire development database. However, it generally warns you before any data loss occurs. (See Figure 2-5.)

9781430250715_Fig02-05.jpg

Figure 2-5. Warnings that appear before data loss occurs

Using LightSwitch Business Types

You’ll find some special data types that you won’t find in other database management systems. These include Email, Money, Phone Number, Web Address, and Percent. These data types are called business types. They’re specially designed to store specialized data and provide built-in validation and data entry controls. These business types include properties that control how LightSwitch displays your data on screen, as well as data entry and validation characteristics. Let’s take a closer look at some of these business types.

Storing Email Addresses

As its name suggests, the Email business type provides storage for email addresses.

When you add an Email field, you’ll find two properties that you can set (as shown in Figure 2-6):

  • Default Email Domain: If the user leaves out the email domain, LightSwitch appends the default email domain that you specify to the end of the email address. This setting is ideal for internal systems that are used by a single company.
  • Require Email Domain: If this is checked, the user must enter an email domain when entering an email address.

9781430250715_Fig02-06.jpg

Figure 2-6. The two Email business type properties

Storing Money Values

When you add a Money field to a table, the additional properties that you can set are shown, as you can see in Figure 2-7. These are

  • Currency Code: Use this field to specify the locale for the currency. For example, if you want to specify United States Dollars, specify USD. Appendix A shows a list of valid codes that you can use.
  • Is Formatted: If you check this, LightSwitch applies formatting when you use the currency control on a screen to display your money value. The formatting that the control applies includes the currency symbol, the grouping separator, and decimal places.

9781430250715_Fig02-07.jpg

Figure 2-7. Properties that you can set on a Money field

The following options apply only if you check the Is Formatted check box:

  • Is Grouped: If checked, LightSwitch shows digit-grouping separators. For example, it displays 1,234,567.89 rather than 1234567.89.
  • Symbol Mode: The symbol mode dropdown allows you to select Currency Symbol, ISO Currency Symbol, or No Currency Symbol. Here are some examples of how LightSwitch would format a money value using the available symbol modes:
  • Currency Symbol: $123.45
  • ISO Currency Symbol: 123.45 USD
  • No Currency Symbol: 123.45
  • Decimal Places: This defines the number of decimal places that LightSwitch shows when it formats a money value.

Storing Phone Numbers

The Phone Number business type is designed to store phone numbers, and it validates data by making sure that users can enter only phone numbers that match a list of predefined formats.

You can define formats by using the dialog that’s shown in Figure 2-8. The symbols that you can use to define a format are

  • C – Country Code
  • A – Area or City Code
  • N – Local number

9781430250715_Fig02-08.jpg

Figure 2-8. Phone Number Formats dialog

Other additional symbols that you can use include the following: +, −, (,), .

When a user enters a phone number through the Phone Number control, the control attempts to validate the phone number against the first format in the list. If the digits match the format, LightSwitch displays the phone number using that format. Otherwise, the control attempts to validate the phone number against all remaining formats in the list until a match is found. If it doesn’t find a match, LightSwitch prevents the record from being saved.

When LightSwitch saves the phone number in the database, it does so without any formatting. If you want to create reports or use the phone number data outside of LightSwitch, you’ll need to write your own procedure to format the data.

Unfortunately, it isn’t possible to specify additional formats on a global or application basis. They must be specified each time a Phone Number field is used in a table.

Storing Web Addresses and Percentage Values

The Web Address business type is new to LightSwitch 2012. It allows you to store Web addresses, and it allows users to add and edit data using the Web Address Editor and Web Address Viewer controls.

Also new to LightSwitch 2012 is the Percent business type. This Business Type allows you to store percentage values. Just like the other business types, LightSwitch provides a Percent Editor and Percent Viewer control for data entry.

Examining What Happens in SQL Server

When you create a table in the table designer, LightSwitch creates the actual table in your Intrinsic SQL Server database. If you create a string property of 255 characters, LightSwitch creates a 255 length nvarchar column (a data type that stores variable length unicode data) in the underlying SQL Server table.

LightSwitch provides an API that allows you to access any property that’s visible in the table designer through code. When you’re writing code, LightSwitch exposes table properties using .NET data types. The mapping between LightSwitch, .NET, and SQL Server data types is shown in Table 2-2.

Table 2-2. Mappings between LightSwitch, .NET, and SQL data types

image

In Table 2-2, notice the business type mappings. LightSwitch uses SQL nvarchar and numeric types as the underlying storage type for business types.

image Tip  Notice how LightSwitch Date and DateTime fields map to the SQL DateTime data type. The minimum date value that you can store is 01-Jan-1753. If you need to store earlier dates (for example, if you’re writing genealogy software), create your tables in an external SQL database and create columns using the DateTime2 datatype (a data type that offers more precision and a greater range of date values).

Creating Choice Lists

Choice Lists allow you to use the Auto Complete Box or Modal Window Picker control to restrict the data values that users can enter. You can specify choice lists on fields from external data sources, as well as on tables that you create yourself in the Intrinsic database.

A choice list is a set of name value pairs, and you can configure these for most data types, including Boolean and numeric types. For example, you can create a choice list for a Boolean field with the choice values of Yes and No. The data types that don’t support choice lists are the image and binary types.

To create a choice list, click the Choice List link on the properties sheet for your field and enter a list of Value and Display Name pairs. When the choices are shown on screen, they’ll appear in the order in which they’re entered. You can re-order the choices by right-clicking the item and selecting the Move Up or Move Down option, as illustrated in Figure 2-9.

9781430250715_Fig02-09.jpg

Figure 2-9. Reorder items using the right-click context menu

LightSwitch saves your choice list settings in the following file: CommonMy ProjectCommon.lsml. It’s possible to maintain your choice list entries by editing this file manually in Notepad. This could be useful if you want to speed up data entry by adding multiple choices using copy and paste, rather than adding them one by one through the Choice List dialog.

image Caution  Always back up and take care before you manually modify an LSML file. You can irreparably damage your LightSwitch solution if you make a mistake. Without a recent backup, you can end up having to re-create your entire LightSwitch solution and redo all of your work.

Choice Lists vs. Related Tables

If you want your users to enter data by choosing from a list of available choices, the choice values can either come from a choice list or a related table.

A choice list is ideal for data items that are relatively static. The disadvantage of using a choice list is that adding or deleting items requires you to recompile and redeploy your application, which can be cumbersome. Table 2-3 summarizes the pros and cons of choice lists and related tables.

Table 2-3. Choice List and Related Table Pros and Cons

Choice List Related Table
✓ Very simple to create. ✗ More complex setup. The choice tables need to be created and relationships need to be set up.
✓ Choice list values are deployed with your application. ✗ An extra step is needed to populate the database table with values.
✗ Adding or deleting requires a rebuild and redeployment of the application ✓ List items can be maintained through the application.
✗ Choice list items must be duplicated if you want to use them in more than one field. ✓ List items can be entered once into a table and used in multiple fields.

Defining Relationships

It’s important to set up relationships between the sets of tables in your application. If not, screen design becomes very difficult, particularly when you want to create parent-child grids or display data through drop-down boxes. The following section describes the various types of relationships you can define.

Defining One-to-Many Type Relationships

One-to-many relationships are a common type of relationship that you can define. This type of relationship allows you to define a data model where a parent record in one table may reference several child records in another table. The following example shows you how to set up your tables so that engineers can be assigned to multiple help desk issues.

To begin, create the Issue and Engineer tables as shown in Figure 2-10. At this point, no relationships have been defined.

9781430250715_Fig02-10.jpg

Figure 2-10. Issue and Engineer tables without relationships

To create the relationship, click the Relationships button in the screen designer toolbar and set up the relationship as shown in Figure 2-11.1

9781430250715_Fig02-11.jpg

Figure 2-11. Creating a one-to-many relationship

The Multiplicity row allows you to define the type of relationship between the two tables—in this case, we’ve created a one-to-many relationship. This means that when a help desk operator creates an issue, they must assign an engineer.

The last row of the dialog allows you to set the Navigation Property names for each table. These allow you to give a meaningful name to the relationship. In our case, we’ve named the Navigation Property on the Issue table AssignedTo.

If you want to add another relationship to the Engineer table (for example, to store the name of the engineer who closes the issue), you can rename the Navigation Property to ClosedBy to distinguish it clearly from the other relationships that might exist between the two tables. The default Navigation Name in this example would be Engineers1, which isn’t very meaningful.

The purpose of a Navigation Property is to give you a way to navigate related entities. When you’re writing code, these properties appear as objects that you can use to reference child and parent entities. You can also query navigation properties by constructing Language Integrated Query (LINQ) expressions in code.

How Relationships Are Defined in SQL Server

With LightSwitch, you can define relationships using simple language and navigation properties. Although this simplifies the process for a novice, it might feel alien for more experienced database developers. If you fall into this category, let’s take a look at what happens when you create a relationship in LightSwitch.

Figure 2-12 compares what you see in the LightSwitch designer with what it creates in SQL Server.

9781430250715_Fig02-12.jpg

Figure 2-12. What you see in LightSwitch (on the left) vs. what you see in SQL Server (on the right)

This diagram shows how we’ve adapted the Issue table in order to store the name of the engineer who closes the issue. This relationship is defined as a (zero-or-one)-to-many relationship, and the navigation property is called ClosedByEngineer. A (zero-or-one)-to-many relationship means that for an issue, specifying a value for “closed by engineer” isn’t mandatory.

For the AssignedTo relationship, notice how LightSwitch creates a column in the issue table called Issue_Engineer. And for ClosedByEngineer, it creates a nullable column called Engineer_Issue. This allows SQL Server to support the (zero-or-one)-to-many relationship that we’ve defined. For both these columns, LightSwitch also creates a SQL Server foreign key relationship to the Id column in the Engineer table.

So when you create relationships in the table designer, LightSwitch carries out the same keying that you would need to carry out if you were to create the tables manually.

Defining Self-Referencing Relationships

Self-referencing or recursive relationships are relationships where entities reference themselves. You’ll often find these when modeling hierarchies. To illustrate this type of relationship, let’s modify the Engineer table so that it stores the name of the engineer’s manager.

To create a self-join, open the relationship dialog and select the same table name in the To side of the relationship, as shown in Figure 2-13. Rename the Navigation Properties to Subordinates (in the From column) and Manager (in the To column). This will result in two navigation properties for the engineer entity, each representing one end of the relationship.

9781430250715_Fig02-13.jpg

Figure 2-13. Setting up a self join in the relationships dialog

Defining Many-to-Many Relationships

In the relationship designer, many-to-many type relationships are not natively supported. If you want to create a many-to-many relationship, you’ll need to create an intermediary table that contains two one-to-many relationships.

In this example, we’ll create a set of tables for storing engineer skills. An engineer can have many skills and a skill can be assigned to one or more engineers.

After creating the Engineer and Skill tables, create an EngineerSkill table to store the many-to-many relationship. In the table designer for the EngineerSkill table, create a one-to-many relationship between the Engineer and EngineerSkill tables. Next, create a one-to-many relationship between the Skill and EngineerSkill tables. Figure 2-14 illustrates the table structure that we have created.

9781430250715_Fig02-14.jpg

Figure 2-14. The data structure behind a many-to-many relationship

This completes the table design; Chapter 7 describes how you can create screens to enter many-to-many data.

Determining How Child Records Are Deleted

When you create a relationship, the ’On Delete Behavior’ setting allows you to determine what happens when a user deletes a record. The three possible options are

  • Cascade delete
  • Restricted
  • Disassociate

In the engineer and issue example, setting the deletion behavior to cascade delete will delete all related issue records when a user deletes an engineer.

If you set the behavior to restricted, engineers can’t be deleted until all related issues have been deleted.

The disassociate option sets all engineer references to null on related issues prior to the deletion of an engineer. The disassociate option is valid only on (zero-or-one)-to-many relationships.

The deletion behavior option is not available and is grayed out if you attempt to create a relationship between two separate data sources. Furthermore, these deletion options are available only for tables that belong in the Intrinsic database. They aren’t available for external data sources.

EXERCISE 2.1 – CREATING TABLES AND RELATIONSHIPS

Open the project that you created in Exercise 1.1, and use the table designer to create some of the tables that are described in this chapter. Appendix E shows a list of tables that you can re-create. For the Engineer table, try adding a property called Engineer. Does LightSwitch allow you to do this? Create the Issue table, and create a one-to-many relationship between the Engineer and Issue tables. After you create these tables, notice how you can view and modify the tables and relationships in the table designer. For these two tables, LightSwitch automatically sets the plural name of your tables to Engineers and Issues. Try creating a table called IssueStatus. What plural name does LightSwitch give this table?

Attaching Existing Data

The other way to use data in LightSwitch is to connect to an existing data source.

LightSwitch allows you to connect a wide range of data sources. When you choose the option to attach to existing data, LightSwitch provides you with four choices. You can attach to a database, a SharePoint list, an OData Service, or a WCF RIA service (Windows Communication Foundation Rich Internet Application service).

The list doesn’t end there, however. As long as there’s an entity framework provider for your data source, LightSwitch can consume your data. This enables you to connect to data sources such as Oracle and MySQL (as shown in Figure 2-15). By downloading third-party data-source providers, you can even attach to social networks such as Facebook.

9781430250715_Fig02-15.jpg

Figure 2-15. Connecting to a MySQL data source

If there isn’t an entity framework provider for your data, you can write your own RIA service, OData service, or even custom data-source extension. These options allow you to connect to data sources that are not natively supported by LightSwitch.

When you attach to an external data source, you can’t add new tables or new fields. You also can’t rename existing fields or modify the schema of other database objects.

However, you can change the data type of an attached field so that it uses a LightSwitch business type. For example, you can configure a SQL Server nvarchar field to use the Phone Number business type rather than a string data type.

image Tip  If you attach a table that contains an image column, LightSwitch sets the data type for that column to binary. If you want the column to behave as an image column and to use the built-in LightSwitch image controls, be sure to open the table in the designer and change the data type from binary to image.

Attaching to an Existing Database

To attach to an existing SQL Server database, right-click the Data node in Solution Explorer and select the Add A Datasource option. Select the Database option, and follow the steps in the wizard.

You’ll eventually reach the dialog that’s shown in Figure 2-16. This allows you to choose the tables and views that you want to use in your LightSwitch application.

9781430250715_Fig02-16.jpg

Figure 2-16. Choose Your Database Objects dialog

Stored procedures, user-defined functions, and other SQL objects are not supported and don’t appear in the dialog that’s shown. If you want to use stored procedures, you can do so by writing a custom RIA service.

image Note  After attaching to an external table, you can use the table designer to reorder the columns. Although this will not affect the underlying SQL table, any new screens that you create will have their data-entry controls ordered in the sequence that you’ve specified.

Dealing with missing tables

If you find that some of your tables are missing from the dialog shown in Figure 2-16, make sure that you’ve defined primary keys on those tables. Tables won’t appear unless primary keys are set up.

If an identity column has been specified but a primary key is not defined, the table will appear but can be added only in read-only mode. (See Figure 2-17). If you’re unfamiliar with SQL Server, identity columns are auto-incrementing fields similar to Sequences in Oracle or Auto Numbers in Access.

9781430250715_Fig02-17.jpg

Figure 2-17. Table attached in read-only mode

Likewise, any views that you want to add must contain a derivable primary key column and can be added only in read-only mode.

Refreshing data sources

If the location of your database server changes, or if the schema of your tables changes, you can refresh your LightSwitch model by right-clicking your data source and choosing the Refresh Data Source option.

When the wizard appears, you can update your database connection details by returning to the very first page in the wizard. Although you can change the connection string from one database server to another, you can’t change the underlying data provider. For example, you can’t change from SQL Server to MySQL without deleting the tables in your application and reimporting.

If the wizard finds any table changes, it indicates these by using a red cross or exclamation point (as shown in Figure 2-18).

9781430250715_Fig02-18.jpg

Figure 2-18. Choose Your Database Objects dialog showing changed items

When you click the Finish button, the wizard updates all screens and removes controls that are bound to the deleted fields. However, any references to these fields in code will not be updated. If references exist in code, they’ll become invalid and will show up in the Error List window. At this point, you can work through the error list and resolve any remaining errors.

DataTime offset and unsupported data types

When you connect to an existing database, there are five SQL types that are currently unsupported. These are the spacial data types geography and geometry, hierarchyid, sql_variant, and datetimeoffset. If you have an existing database that uses any of these data types, LightSwitch won’t be able to read or write to those fields.

Datetimeoffset is the data type that gives developers the most problems. It’s commonly used in applications that span multiple time zones, but it is currently unsupported in LightSwitch.

If you want to create an application that supports multiple time zones, the simplest solution is to save all datetime values in UTC (Coordinated Universal Time). You can use server-side code to ensure that all dates are saved in this format (Chapter 4 shows you how to write code that runs on the server). The .NET datetime class contains a DateTime.ToUniversalTime method that you can use to convert times.

image Tip  If you save your date values in UTC, you’ll never encounter daylight saving problems. For example, if you create an application that calculates employee working hours by storing the start and end dates and times, you won’t incorrectly pay an employee for an extra hour if they choose to work when the clocks go forward.

Attaching to SharePoint Data

You can connect your application to a SharePoint 2010 data source. LightSwitch uses a custom OData provider, so it doesn’t support versions prior to SharePoint 2010.

You can attach to SharePoint lists using the Data Source wizard in the same way that you would connect to a SQL Server database.

There are various limitations when using SharePoint data. First, LightSwitch isn’t able to manage SharePoint attachments or documents. Second, there’s limited support for the SharePoint column types of Picture and Hyperlink. This is because LightSwitch doesn’t include any native controls for showing these data items. It also doesn’t fully support multiline text because LightSwitch doesn’t include a native HTML control that allows users to edit the content.

Deleting a Data Source

If you delete a data source, LightSwitch removes all entities that relate to that data source from all screens in your application. The screens themselves will not be deleted, but instances of entities and related controls within those screens will be removed.

Creating Computed Properties

Computed properties are special properties that derive their values through calculations and possibly from other fields. Computed properties are read-only by definition and appear in the entity designer with a calculator icon next to the field. A slight limitation of computed properties is that you can’t use them in your HTML client applications.

Computed properties are very versatile. The code that you write belongs in your Common project, and LightSwitch executes this code both on the Silverlight client and server. From a practical point of view, this means that LightSwitch can immediately recalculate a computed property and show the result on screen without requiring any intervention that triggers a server event, such as clicking on the Save button on the screen.

You’ll now see several examples of computed properties. This will give you a flavor of the type of code that’s involved in constructing a computed property.

image Tip  There’s nothing to prevent you from creating a computed property on an attached table. Computed properties are not just limited to tables that you create in the Intrinsic database.

Creating Summary Properties

Each table allows you to specify a summary property through the properties sheet in the table designer. Summary properties are designed to summarize the contents of a data row for display purposes. To show a summary property on a screen, you’d use a summary control. This control is most often used in grids and autocomplete boxes.

In the example that follows, we’ll create a computed property in the Engineer table called FullName that concatenates the first name and surname of an engineer.

Open the Engineer table, and create a new property called FullName. In the General section of the properties sheet for the new property, check the Is Computed check box. Click on the Edit Method hyperlink, and enter the code that’s shown in Listing 2-1.

Listing 2-1.  Formatting Strings in a Computed Property

VB:
File: HelpDeskVBCommonUserCodeEngineer.vb
  
Private Sub FullName_Compute(ByRef result As String)
    result = String.Format("{0} - {1}", Surname, Firstname)
End Sub
  
C#:
File: HelpDeskCSCommonUserCodeEngineer.cs
  
partial void FullName_Compute(ref string result)
{
    result = String.Format("{0} - {1}", this.Surname, this.Firstname);
}

This code demonstrates how to format strings using .NET’s String.Format method. This method accepts two parameters. The first parameter specifies the string to be displayed and includes placeholders in the format {0},{1} and so on. The second parameter accepts a comma-separated list of data items, which are then substituted into the display string.

To set this as the summary property, open the properties sheet for the Engineer table and choose FullName from the Summary Property drop-down list (as shown in Figure 2-19 images).

Figure 2-19 images shows the FullName summary property on a screen that’s designed for entering new issues.

9781430250715_Fig02-19.jpg

Figure 2-19. Summary Property set to a computed field

Calculating Dates with Computed Properties

You can use computed properties to calculate dates. This example shows you how to calculate the difference between two dates. The Engineer table contains a date of birth field. By using a computed property, you can calculate the age of a person in years.

To do this, create an integer computed property called Age and enter the code that’s shown in Listing 2-2.

Listing 2-2.  Calculating Date Differences

VB:
File: HelpDeskVBCommonUserCodeEngineer.vb
  
Private Sub Age_Compute(ByRef result As Integer)
    result = DateDiff(DateInterval.Year, DateOfBirth, Now)
End Sub
  
C#:
File: HelpDeskCSCommonUserCodeEngineer.cs
  
partial void Age_Compute(ref int result)
{
    DateTime now = DateTime.Today;
    int age = now.Year - DateOfBirth.Year;
    if (DateOfBirth > now.AddYears(-age)) age--;
    result = age;
}

This code illustrates the use of the VB.NET DateDiff function. This function allows you to calculate date and time differences accurately, and also takes leap years into consideration. C# doesn’t have an equivalent method, and the calculation is therefore slightly more complex.

image Caution  Computed property values are cached by the Silverlight client. This can result in incorrect results if you decide to use computed properties to calculate real-time data (for example, the number of minutes since a support issue was opened).

Summarizing Child Records with Computed Properties

You can easily refer to related records through navigation properties. In this example, we’ll create a computed property in the Engineer table that returns the number of help desk issues that are assigned to each engineer.

To do this, create a computed property called IssueCount and enter the code that’s shown in Listing 2-3.

Listing 2-3.  Using Navigation Properties in a Computed Property

VB:
File: HelpDeskVBCommonUserCodeEngineer.vb
  
Private Sub IssueCount_Compute(ByRef result As Integer)
    result = Issues.Count()
End Sub
  
C#:
File: HelpDeskCSCommonUserCodeEngineer.cs

partial void IssueCount_Compute(ref int result)
{
    result = this.Issues.Count();
}

The code in Listing 2-3 demonstrates how to refer to child items in a computed property. Specifically, it shows you how to use the aggregate count operator against a navigation property. Other aggregate operations that you can use include Sum and Average.

Returning Images with Computed Properties

You’re not just limited to returning string and numeric data in a computed property. This example shows you how to create a computed property that returns an image. If the current date exceeds the target end date, the computed property returns a warning icon. Otherwise, it returns a blank white image.

To create this example, create a computed image property called icon and enter the code that’s shown in Listing 2-4.

Listing 2-4.  Creating a Computed Property That Returns an Image

VB:
File: HelpDeskVBCommonUserCodeIssue.vb
  
Private Sub Icon_Compute(ByRef result As Byte())
    If TargetEndDateTime < DateTime.Now Then
        ' this string has been truncated for brevity
        Dim base64EncodedImage = "/9j/4A..."
        result = Convert.FromBase64String(base64EncodedImage)
    Else
        result = Nothing
    End If
End Sub
  
C#:
File: HelpDeskCSCommonUserCodeIssue.cs
  
partial void Icon_Compute(ref byte[] result)
{
    if (TargetEndDateTime < DateTime.Now)
    {
        // this string has been truncated for brevity
        string base64EncodedImage = @"/9j/4A...";
        result = Convert.FromBase64String(base64EncodedImage);
    }
    else
    {
        result = null;
    }
}

The computed property returns a hardcoded, base 64 encoded image. There are various web sites that allow you to upload an image and to find out its base 64 encoding. Alternatively, you can retrieve the image from a table, and Chapter 4 shows you how to access data from code. Figure 2-20 shows an example of how this computed property appears on a data grid.

9781430250715_Fig02-20.jpg

Figure 2-20. A computed column that returns an image

Sorting and Filtering by Computed Properties

A slight limitation of computed properties is that you can’t sort or filter by these fields. If you create a query that uses a table with computed properties, these fields will not appear in the drop-down list of available fields when you’re creating a filter or sort.

If you need to sort grids by computed properties, a possible workaround is to use a SQL Server computed field rather than a LightSwitch computed property. This approach will work only with data in an external SQL data source. Furthermore, SQL Server computed columns are less powerful because you can’t refer to data in other tables.

If you want to sort a table by a computed value, you can do this by creating a query and writing code in the PreProcessQuery method. Chapter 6 shows you how to do this.

Summary

To work with data, you can create tables in the Intrinsic database or connect to existing data sources. A single LightSwitch application can consume multiple data sources, and you can pretty much work with any data source that you want. If LightSwitch doesn’t support your data source, you can write an RIA service or Custom Data Source extension to access your data. The data sources that LightSwitch natively supports include SQL Server, SharePoint, OData, and RIA services.

During development, LightSwitch hosts your Intrinsic database using LocalDB (the successor to SQL Server Express). LightSwitch persists any data you add at design time between debug sessions. However, you should be aware that there isn’t a built-in way to deploy your design-time data into your live SQL Server environment.

LightSwitch uses the term entity to refer to a row of data from a table, and the term property to refer to a field or column in a table.

You can store your data using standard data types, such as strings and integers. But unlike other databases, you can also store rich data types like web addresses, phone numbers, and email addresses. These data types are called business types. They provide you with custom validation and specialized data-entry controls, and you can take advantage of these features by simply setting the type of a field to a business type.

Business types use native data types for their underlying storage. This means that they’re not limited to fields in your Intrinsic database. You can also apply business types to table fields that belong in attached data sources.

You can set up relationships between tables, even if your tables belong in different data sources. It’s important to define relationships on your tables; otherwise, you’ll find it very difficult to design screens later on.

If you want your users to enter data by choosing from a list of predefined selections, you can either use a related table or create a choice list. Choice lists are ideal for storing static lists of data that rarely change.

To carry out math and logic at an entity level, you can attach computed properties to your tables. These allow you to define row-level calculations that you can make available throughout your application. Computed properties aren’t just limited to tables in your Intrinsic database. You can also create them against tables in attached databases. One caveat is that you can’t sort or filter collections of entities using computed columns.

1 Notice how it produces the sentence ‘a engineer (sic)’, rather than ‘an engineer’. If this annoys you too, you could rename your tables so that they don’t begin with vowels. However, I’d recommend that you spend your time doing something  else more meaningful!

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.79.20