Implementing Line of Business applications has never been easier before. RIA services together with the rich presentation layer in Silverlight provide a powerful foundation for building n-tier application that will do the heavy lifting of your data layer.
RIA Services relies on the ADO.NET Entity Framework to create an entity data model of your relational database and interpret the entities independently of their data store representation. In this way you can use the power of LINQ to Entities to implement query logic against the entities without using t-sql, and rely on the entity relationship to retrieve information for any relationship between two entities. Simple as that, you won’t implement any queries that accept a foreign key of a table, and return let’s say a Name associated with this ID in the relationship table. All of this will be explained in a couple of articles I will post on how to take full advantage of RIA Services and RadControls for Silverlight. In this demo I use RadComboBox to retrieve data from a database, but in future blogs I will focus on the powerful combination of RadGridView and RIA Services.
First of all, in order to build your n-tier application you have to create an ASP.NET application that will host your ADO.NET Entity Model and eventually integrate it with a Silverlight application that will make us of the data model. To do that, I have created a simple demo in Silverlight 3 that demonstrates the use of RIA Services:
Prerequisites:
RIA Services
Silverlight 3
Running instance of SQL Server
To get started I have implemented a simple database called AdventureWorks that has a single table User, you can use an existing database or create the one I use by executing the sql scripts found in the solution folder Scripts as shown below.
The reason I don’t include an .mdf file with an existing database in the solution is that I have found some problems using an mdf file when there is only SQL Server 2008 installed, more information can be found here . After you have created your database you can put some dummy records.
To create a Silverlight application that uses the ASP.NET application as a data layer, you should create ASP.NET Web Application Project and click the Link to ASP.NET Server project as shown below.
If you want to link an existing Silverlight 3 project with your data layer, just go to the properties of your Silverlight application and set the ComboBox shown below to choose the data layer part of your solution.
To add your ADO.NET Entity Model
1. Go to your Web applicaton
2. Select add new item
3. Add new ADO.NET Entity Data Model
4. Enter your data connection and select the catalog you want to use. In my case AdventureWorks, and then select the database objects you want to include in your data model. Like this:
5. Build your application.
Now we have created our Data Model and we would like to create a domain service that will be used in our Silverlight application to create, read, update and delete data against the entity model.
1. Go to your Web application
2. From the add new item menu select Domain Service Class like below:
3. Click Add and choose the entity that will be used by the service. If you click on the Enable editing checkbox the framework will also generate methods for insert, remove and modify operations. In case you only need read operations, don’t check this box. In this demo I have checked the checkbox as shown below:
Note that there is also an option to generate metadata for this class; in this demo we won’t use this option as it’ll be the subject of next posts. If you now open your file you will notice that the class is decorated by the EnableClientAccess() attribute. This tells the framework to generate a proxy class in our Silverlight application which we have referenced a few minutes ago. Thus, if we build now our Web application and go to the Silverlight project and click on Show All Files, we will see that there is a generated code that comes from the Web application as shown below.
The framework generated a UserContext class that refers to the UserService class in our Web Project. Note that the GetUser() method you have in your UserService class is not replaced by LoadUser() since the data is asynchronously transferred. Our UserContext class is available in RadGridViewAndRIA.Web namespace. If you just type UserContext and wait for the intellisense to tell you where the assembly is located, you will see that there is also a UserContext class in the System.Windows.Ria.Data assembly. This class has nothing to do with our implementation and is used for Authentication logic, for more information on Authentication techniques in RIA check the document at the end of this blog.
Now we can use our UserContext class to load data asynchronously from the data layer and use it in a context. Let’s use a single RadComboBox to populate column FirstName and LastName from our database. For this, we need to create a simple RadComboBox with an ItemTemplate that will hold two TextBlocks for showing the columns. Here is a sample implementation of this:
<input:RadComboBox x:Name="cmbUsers" ItemsSource="{Binding}"> |
<input:RadComboBox.ItemTemplate> |
<DataTemplate > |
<Grid> |
<Grid.ColumnDefinitions> |
<ColumnDefinition Width="*"/> |
<ColumnDefinition Width="*"/> |
</Grid.ColumnDefinitions> |
<TextBlock Text="{Binding FirstName}" Grid.Column="0" /> |
<TextBlock Margin="15,0,0,0" Grid.Column="1" Text="{Binding LastName}" /> |
</Grid> |
</DataTemplate> |
</input:RadComboBox.ItemTemplate> |
</input:RadComboBox> |
We can bind the ComboBox either using the code-behind or declare one of the new controls that comes with the Ria package – DomainDataSource.
In code-behind:
Declare the UserContext service as a member variable in order to use is throughout our class, and call the LoadUser() method which will asynchronously load data from the database.
public partial class MainPage : UserControl |
{ |
UserContext context; |
public MainPage() |
{ |
InitializeComponent(); |
context = new UserContext(); |
context.LoadUser(); |
context.Loaded += new EventHandler<LoadedDataEventArgs>(OnUserDataLoaded); |
} |
void OnUserDataLoaded(object sender, LoadedDataEventArgs e) |
{ |
cmbUsers.DataContext = context.Users; |
} |
} |
If you want to skip the code-behind implementation, you can declare a DomainDataSource that uses our UserContext and bind it to the ComboBox like this:
In xaml declaration:
<ria:DomainDataSource x:Name="domainDS" AutoLoad="True" LoadMethodName="LoadUser"> |
<ria:DomainDataSource.DomainContext> |
<web:UserContext /> |
</ria:DomainDataSource.DomainContext> |
</ria:DomainDataSource> |
<input:RadComboBox x:Name="cmbUsers" ItemsSource="{Binding Data, ElementName=domainDS}"> |
<input:RadComboBox.ItemTemplate> |
<DataTemplate > |
<Grid> |
<Grid.ColumnDefinitions> |
<ColumnDefinition Width="*"/> |
<ColumnDefinition Width="*"/> |
</Grid.ColumnDefinitions> |
<TextBlock Text="{Binding FirstName}" Grid.Column="0" /> |
<TextBlock Margin="15,0,0,0" Grid.Column="1" Text="{Binding LastName}" /> |
</Grid> |
</DataTemplate> |
</input:RadComboBox.ItemTemplate> |
</input:RadComboBox> |
In my next blog post I will talk about how to populate RadGridView using the UserContext class.
For downloading the latest version of RIA Services and the official overview document click here . Today, Microsoft released their new May Preview version of the services, which includes a lot of bug fixes and improvements.
You can download the project described in this article here RadComboBoxAndRIA.rar