Silverlight and RIA Services - Part II
Part I of this article on RIA Services demonstrated how easy it is to display data from the database. I’ll now take this one step further and show you how to insert, update and delete data using RIA Services. Before beginning you should read Part I of this article, as I’ll be using the project from it. You must also install the latest RIA Services package from Microsoft. As of writing this the July 2009 version is the latest version. You can download it from here. I recommend that you also download the accompanying PDF, which provides a lot of detail, and plenty of good code samples. Also this is using some controls from the Silverlight 3 Toolkit which can be downloaded from here.
To begin with open up the project from Part I. Right now the DomainService class, NorthwindService, only has the one method, GetCustomers. Now I want to have the full set of CRUD methods in there. For this example I am going to be using the Suppliers table, not the Customers table. The easiest way to generate your CRUD methods is to delete the NorthwindService file and add a new DomainService class. Name it NorthwindService:
The Add New Domain Service Class dialog appears. Select the Suppliers object and tick the Enable Editing check box before clicking OK:
The file is created. Instead of the one method, now you have four methods created for you:
C#
public IQueryable<Supplier> GetSuppliers()
{
return this.Context.Suppliers;
}
public void InsertSuppliers(Supplier suppliers)
{
this.Context.AddToSuppliers(suppliers);
}
public void UpdateSuppliers(Supplier currentSuppliers)
{
this.Context.AttachAsModified(currentSuppliers,
this.ChangeSet.GetOriginal(currentSuppliers));
}
public void DeleteSuppliers(Supplier suppliers)
{
if ((suppliers.EntityState == EntityState.Detached))
{
this.Context.Attach(suppliers);
}
this.Context.DeleteObject(suppliers);
}
VB.NET
Public Function GetSuppliers() As IQueryable(Of Supplier)
Return Me.Context.Suppliers
End Function
Public Sub InsertSuppliers(ByVal suppliers As Supplier)
Me.Context.AddToSuppliers(suppliers)
End Sub
Public Sub UpdateSuppliers(ByVal currentSuppliers As Supplier)
Me.Context.AttachAsModified(currentSuppliers, Me.ChangeSet.GetOriginal(currentSuppliers))
End Sub
Public Sub DeleteSuppliers(ByVal suppliers As Supplier)
If (suppliers.EntityState = EntityState.Detached) Then
Me.Context.Attach(suppliers)
End If
Me.Context.DeleteObject(suppliers)
End Sub
This is all that’s required for the web application. Open up the Silverlight application. For this example all the user will see is the DataGrid control. We’ll do the inserts, updates and deletes using the DataGrid in conjunction with the RIA Services DomainDataSource control. Add the following xaml to the MainPage.xaml file:
<Grid x:Name="LayoutRoot">
<riaControls:DomainDataSource QueryName="GetSuppliers"
AutoLoad="True"
x:Name="dds">
<riaControls:DomainDataSource.DomainContext>
<web:NorthwindContext />
</riaControls:DomainDataSource.DomainContext>
</riaControls:DomainDataSource>
<StackPanel Orientation="Vertical">
<data:DataGrid x:Name="dgSupplier"
IsReadOnly="False"
ItemsSource="{Binding Data, ElementName=dds, Mode=OneWay}"
Width="700" Height="500"
KeyUp="dgSupplier_KeyUp"
RowEditEnding="dgSupplier_RowEditEnding">
</data:DataGrid>
<Button x:Name="btnUpdate" Content="Update"
IsEnabled="False" Width="100" Height="25"
Click="btnUpdate_Click"/>
</StackPanel>
</Grid>
That’s it for the xaml! The DomainDataSource control takes care of all the heavy lifting for connecting the client to the database, and Silverlight data binding takes care of the code for displaying the data. When you need to perform general CRUD work then it’s time to write some code.
To begin with I have created a property that holds a reference to the DomainDataSource’s DomainContext:
C#
private DomainContext Context
{
get
{
return dds.DomainContext;
}
}
VB.NET
Private ReadOnly Property Context() As DomainContext
Get
Return dds.DomainContext
End Get
End Property
Then in the constructor you need to create an event handler that is raised whenever a property has changed to a supplier entity in the DataGrid. The UpdateHasChanges main purpose is to enable/disable the button so that it is enabled when the user changes data, and disabled when they’re not:
C#
public MainPage()
{
InitializeComponent();
Loaded += new RoutedEventHandler(MainPage_Loaded);
}
void MainPage_Loaded(object sender, RoutedEventArgs e)
{
Context.Entities.PropertyChanged += (s, o) =>
{
if (o.PropertyName == "HasChanges")
{
UpdateHasChanges();
}
};
}
private void UpdateHasChanges()
{
EntityChangeSet changes = Context.Entities.GetChanges();
btnUpdate.IsEnabled = Context.HasChanges;
}
VB.NET
Public Sub New()
InitializeComponent()
AddHandler Loaded, AddressOf MainPage_Loaded
End Sub
Private Sub MainPage_Loaded(ByVal sender As Object, ByVal e As RoutedEventArgs)
AddHandler Context.Entities.PropertyChanged, Function(s, o) AnonymousMethod1(s, o)
End Sub
Private Function AnonymousMethod1(ByVal s As Object, ByVal o As Object) As Boolean
If o.PropertyName = "HasChanges" Then
UpdateHasChanges()
End If
Return True
End Function
Private Sub UpdateHasChanges()
Dim changes As EntityChangeSet = Context.Entities.GetChanges()
btnUpdate.IsEnabled = Context.HasChanges
End Sub
Deleting Data
To delete data in this example, the user will hit the delete key on their keyboard. The code below shows you how to delete the selected supplier:
C#
private void dgSupplier_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Delete && dgSupplier.SelectedItem != null)
{
var supplier = dgSupplier.SelectedItem as Supplier;
(dds.DomainContext as NorthwindContext).Suppliers.Remove(supplier);
UpdateHasChanges();
}
}
VB.NET
Private Sub dgSupplier_KeyUp(ByVal sender As Object, ByVal e As KeyEventArgs)
If e.Key = Key.Delete AndAlso dgSupplier.SelectedItem IsNot Nothing Then
Dim supplier = TryCast(dgSupplier.SelectedItem, Supplier)
TryCast(dds.DomainContext, NorthwindContext).Suppliers.Remove(supplier)
UpdateHasChanges()
End If
End Sub
To delete the selected supplier, the record must first be removed from the list of suppliers in the RIA Service. Once that is removed, UpdateHasChanges is called to enable the update button.
Inserting Data
To insert data it’s not as straight forward as I thought. The way to do it is not to add a new row to the DataGrid, but to add a new blank supplier and let our RIA Service update the DataGrid with the blank row. The code below shows you how to insert a new supplier:
C#
private void dgSupplier_KeyUp(object sender, KeyEventArgs e)
{
if (e.Key == Key.Insert)
{
(dds.DomainContext as NorthwindContext).Suppliers.Add(new Supplier()
{
Address = "", City = "",
Country = "", PostalCode = "",
Region = "", CompanyName = "",
ContactName = "", ContactTitle = "",
Fax = "", Phone = ""
});
dds.SubmitChanges();
dds.Load();
}
}
VB.NET
Private Sub dgSupplier_KeyUp(ByVal sender As Object, ByVal e As KeyEventArgs)
If e.Key = Key.Insert Then
TryCast(dds.DomainContext, NorthwindContext).Suppliers.Add(New Supplier() With {.Address = "", .City = "", .Country = "", .PostalCode = "", .Region = "", .CompanyName = "", .ContactName = "", .ContactTitle = "", .Fax = "", .Phone = ""})
dds.SubmitChanges()
dds.Load()
End If
End Sub
The new supplier will be added to the bottom of the DataGrid. The Load method is executed on the DomainDataSource re-binds the new data to the DataGrid. The code for the update button is as follows:
C#
private void btnUpdate_Click(object sender, RoutedEventArgs e)
{
Context.SubmitChanges(DataSaved, null);
}
private void DataSaved(SubmitOperation sender)
{
}
VB.NET
Private Sub btnUpdate_Click(ByVal sender As Object, ByVal e As RoutedEventArgs)
Context.SubmitChanges(AddressOf DataSaved, Nothing)
End Sub
Private Sub DataSaved(ByVal sender As SubmitOperation)
End Sub
All changes are submitted to the database via the DomainContext’s SubmitChanges method. If there are any errors during the process they will be passed back to the DataSaved function through the SubmitOperation class. Now you can add, edit and delete suppliers all from the comfort of the one control, and it’s using RIA Services. Pretty cool huh?!
I hope you have enjoyed reading the second part of this article. I have enjoyed writing about RIA Services and I hope you find them interesting too. They do make your life easier when it comes to Silverlight development, so start using them today!
The entire source code of this article can be downloaded over here
If you liked the article,
Subscribe to the RSS Feed or Subscribe Via Email
Malcolm Sheridan is an independent contractor who has been working with Microsoft technologies since VB4. Malcolm has worked with .NET since its inception and thoroughly enjoys ASP.NET.
This article has been editorially reviewed by Suprotim Agarwal.
C# and .NET have been around for a very long time, but their constant growth means there’s always more to learn.
We at DotNetCurry are very excited to announce The Absolutely Awesome Book on C# and .NET. This is a 500 pages concise technical eBook available in PDF, ePub (iPad), and Mobi (Kindle).
Organized around concepts, this Book aims to provide a concise, yet solid foundation in C# and .NET, covering C# 6.0, C# 7.0 and .NET Core, with chapters on the latest .NET Core 3.0, .NET Standard and C# 8.0 (final release) too. Use these concepts to deepen your existing knowledge of C# and .NET, to have a solid grasp of the latest in C# and .NET OR to crack your next .NET Interview.
Click here to Explore the Table of Contents or Download Sample Chapters!
Was this article worth reading? Share it with fellow developers too. Thanks!
Malcolm Sheridan is a Microsoft awarded MVP in ASP.NET, a Telerik Insider and a regular presenter at conferences and user groups throughout Australia and New Zealand. Being an ASP.NET guy, his focus is on web technologies and has been for the past 10 years. He loves working with ASP.NET MVC these days and also loves getting his hands dirty with jQuery and JavaScript. He also writes technical articles on ASP.NET for SitePoint and other various websites. Follow him on twitter @
malcolmsheridan