(X) Hide this
    • Login
    • Join
      • Say No Bots Generate New Image
        By clicking 'Register' you accept the terms of use .
        Login with Facebook

Creating applications with WCF NET RIA Services Part 4 - Adding a DomainDataSource

(1 votes)
Martin Mihaylov
>
Martin Mihaylov
Joined Oct 29, 2007
Articles:   50
Comments:   70
More Articles
7 comments   /   posted on Apr 01, 2009
Categories:   Data Access , Line-of-Business
This article has been written for an older version of WCF RIA Services. To find out how to use the latest version of the WCF RIA Services read the dedicated article series and webinars by Brian Noyes.
WCF RIA Services Part 1: Getting Started | Watch the webinar recording

Introduction

By now we have discussed the preparations around the project, how to add a DomainService that contains our business logic and combine it with the entity framework.

As you know from the previous articles in order to demonstrate the features of the WCF RIA Services I am creating the Web Administration Tool from ASP.NET in Silverlight. In this article I am going to create the Manage Users page and add the functionality needed to visualize Data. For that purpose I will need the DataGrid control, the new DataPager control and the DomainDataSource that is a part of the WCF RIA Services framework.

Here is a link to the live demo at this stage and the source code. Note that they will be updated with each article! ;)

Adding the DomainDataSource control

The DomainDataSource control can be found in the Systems.Web.Ria.Controls assembly and we have to declare the proper namespace in order to use it:

<navigation:Page x:Class="WebAdministrationTool.ManageUsers" 
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
           ...
           xmlns:ria="clr-namespace:System.Windows.Controls;assembly=System.Windows.Ria.Controls"
           ...
           Title="ManageUsers Page">
    <Grid x:Name="LayoutRoot">
        ...
        <ria:DomainDataSource x:Name="UsersDataSource"></ria:DomainDataSource>
        ...
    </Grid>
</navigation:Page>

The next step is to configure the DomainDataSource control to work with our DomainService class named UsersManager, which we have created in the previous article. The only thing we have to do is to set the DomainContext property:

<navigation:Page x:Class="WebAdministrationTool.ManageUsers" 
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
           ... 
           xmlns:ria="clr-namespace:System.Windows.Controls;assembly=System.Windows.Ria.Controls"
           xmlns:local="clr-namespace:WebAdministrationTool"
           ...
           Title="ManageUsers Page">
<Grid x:Name="LayoutRoot">
    ...
    <ria:DomainDataSource x:Name="UsersDataSource" LoadMethodName="LoadAspnet_Users">
        <ria:DomainDataSource.DomainContext>
            <local:UsersManager />
        </ria:DomainDataSource.DomainContext>
    </ria:DomainDataSource>
    ...
</Grid>
</navigation:Page>

As the UsersManager class can be accessed through the generated code on the client we declare the namespace of our project in the XAML. We also specify the method that the DomainDataSource should use in order to load the data from the data base. Note that on the server our method is named GetAspnet_Users, but on the client it’s LoadAspnet_Users (see in the previous article how to use the DomainService on the client by using the managed code).

Adding a DataGrid control to the scene

Now as we have our DomainDataSource control prepared let’s add a Grid and bind them together:

<data:DataGrid x:Name="UsersGrid" 
                       IsReadOnly="True" 
                       AutoGenerateColumns="False" 
                       HeadersVisibility="None" 
                       GridLinesVisibility="None">
    <data:DataGrid.ItemsSource>
        <Binding ElementName="UsersDataSource" Path="Data" />
    </data:DataGrid.ItemsSource>
    <data:DataGrid.Columns>
        <data:DataGridTextColumn Binding="{Binding UserName}" />
    </data:DataGrid.Columns>
</data:DataGrid>

Using the Element-to-Element binding that came with Silverlight 3 we bind the ItemsSource of the DataGrid to the Data property of the DomainDataSource control.

Now let’s add a row details to our DataGrid, which will give more information about the selected user. First let’s take a look at the GetAspnet_Users of the UsersManager DomainService on the server:

public IQueryable<aspnet_Users> GetAspnet_Users()
{
    return this.Context.aspnet_Users;
}

It returns the content of the aspnet_Users table. In this table the only information we have is the username. The email, the comment and if the user is active can be found in the aspnet_Membership table and the information about the roles, that the user is in, is located in the aspnet_UsersInRoles table. These two tables are in relation with the aspnet_Users table and the associations between them are defined in the data model, so we can modify the get method in the following way:

public IQueryable<aspnet_Users> GetAspnet_Users()
{
    return this.Context.aspnet_Users.OrderBy( "it.UserName" )
                       .Include( "aspnet_Membership" )
                       .Include( "aspnet_UsersInRoles" );
}

In the previous article we configured the metadata for the aspnet_Users, so we can now use the following properties on the client:

internal sealed class aspnet_UsersMetadata
{
    ...
    [Include]
    public aspnet_Applications aspnet_Applications;
 
    [Include]
    public aspnet_Membership aspnet_Membership;
 
    [Include]
    public EntityCollection<aspnet_UsersInRoles> aspnet_UsersInRoles;
    ...
}

When the query is executed they are populated with the proper data. Now back on the client we have the following row details template for the DataGrid:

<data:DataGrid x:Name="UsersGrid"
               IsReadOnly="True"
               AutoGenerateColumns="False"
               HeadersVisibility="None"
               GridLinesVisibility="None">
        ...
    <data:DataGrid.RowDetailsTemplate>
        <DataTemplate>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto" />
                    <ColumnDefinition />
                </Grid.ColumnDefinitions>
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                    <RowDefinition Height="Auto" />
                </Grid.RowDefinitions>
                <TextBlock x:Name="IsActiveLabel" Text="Is active: " FontWeight="Bold" Grid.Column="0" Grid.Row="0" />
                <TextBlock x:Name="IsActiveBlock" 
Text
="{Binding aspnet_Membership.IsApproved,Converter={StaticResource BooleanConverter}}"
Grid.Column="1" Grid.Row="0" />
                <TextBlock x:Name="EmailLabel" Text="E-mail: " FontWeight="Bold" 
Grid.Column="0" Grid.Row="1" />
                <TextBlock x:Name="EmailBlock" Text="{Binding aspnet_Membership.Email}" 
Grid.Column="1" Grid.Row="1" />
                <TextBlock x:Name="DescriptionLabel" Text="Description: " FontWeight="Bold" 
Grid.Column="0" Grid.Row="2" />
                <TextBlock x:Name="DescriptionBlock" Text="{Binding aspnet_Membership.Comment}" 
Grid.Column="1" Grid.Row="2" />
            </Grid>
        </DataTemplate>
    </data:DataGrid.RowDetailsTemplate>
    ...
</data:DataGrid>

That’s it!

Paging the data

There is one last thing left to do – to add paging to the DomainDataSource. That can be easily accomplished by using the DataPager control (introduced with Silverlight 3). The control is located in the System.Windows.Controls.Data.DataForm assembly, so once again we have to declare a namespace in our XAML:

<navigation:Page x:Class="WebAdministrationTool.ManageUsers" 
           xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
           xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
            ...
           xmlns:validation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm"
            ...
           Title="ManageUsers Page">
    <Grid x:Name="LayoutRoot">
        ...
        <validation:DataPager x:Name="UsersPager"
                              PageSize="10" 
                              Source="{Binding Data, ElementName=UsersDataSource}" />
    </Grid>
</navigation:Page>

Once bound to the Data property of the DomainDataSource control it handles the paging itself, we just have to set its page size. The most important thing to mention is that the DataPager control can page collections which implement the IPagedCollectionView interface. The Data property is such a collection.

Also here the LoadSize property of the DomainDataSource control can be found useful. It determines the count of the items to be loaded in the Data property of the control. For example I can set it to 10 and each time the page is changed only 10 items will be loaded. In the common case we set it to a number multiple to the page size. Another option is to set it to the count of the items, if it is known, so all items will be loaded and no other requests to the server will be made.

Note: The DataPager doesn't work with unsorted collections, because the Skip and Take extension methods, that the control uses, are unavailable for such them. By default the EntityFrameowrk returns unsorted data and that's why I have added an OrderBy to my query. The other way is to sort the data on the client via the DomainDataSource control, but that will be the subject of my next article.

Conclusion

In this article I explained some basics about the DomainDataSource, the DataGrid and the DataPager controls. Thanks to them the loading and the visualization of data is not as tough as it was before. In the next article we’ll see how they allow us to easily apply sorting and filtering to the loaded data.

If you have any questions, I’ll be glad to answer them. :)


Subscribe

Comments

  • -_-

    RE: Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource


    posted by Rob on Apr 04, 2009 01:38
    Is it possible to use .Net RIA Services with Azure Table Storage.
  • -_-

    RE: Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource


    posted by Jonathan on May 29, 2009 19:02
    I get an error whenever I try to add the domain datasource to my xaml file:
    http://silverlight.net/forums/p/99299/226646.aspx#226646

    do you have any ideas about this?

  • -_-

    RE: Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource


    posted by silverlight man on Jun 20, 2010 12:14

    I get this error when i make a getaspnetUser :

    Problem in mapping fragment starting at lines 67 , 75 :

    Foreign key constraints FK_aspnet_Us_Role from table aspnet_UserInRoles (RoleId) to table aspnetRoles

    Insufficent mapping : foreing key must be mapped to some associationSet etc....

  • -_-

    RE: Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource


    posted by anonymous on Jun 21, 2010 09:53

    Your project doesn't work in silverlight 4.0 and RIA 1.0 with visual studio 2010...

     

  • -_-

    RE: Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource


    posted by George on Nov 09, 2010 18:12
    Could you convert this project/example to work with silverlight 4 vs2010 ?
  • -_-

    RE: Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource


    posted by Ricky on Dec 01, 2010 09:02
    I wonder if any of the examples/projects shown on www.silverlightshow.net actually work when you TRY to reproduce them on your own machine. It is amazing how there is so much information and examples available, yet not one describes a step by step approach. It is very frustrating to try this and spent hours on searching why something is not working, to then find out on your own that you should have added a reference of which ofcourse no word gets written in the "example".
  • -_-

    RE: Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource


    posted by asdasdasda on Jan 29, 2011 16:38
    (X) Hide this Upcoming webinar by Brian Noyes: Querying and Updating Data From Silverlight Clients with WCF RIA Services. February 2nd, 10 am PST (see your local time)
    Full webinar info | Register | Read WCF RIA Services Article series by Brian Noyes
    Become a member to receive all webinar news by email, or follow all webinar news on Twitter | Facebook | LinkedIn
    Skip Navigation LinksHome / Articles / View Article

    Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource

    + Add to SilverlightShow Favorites
    6 comments   /   posted by Martin Mihaylov on Apr 01, 2009
    (1 votes)
    Categories: Demos , Learn , Tutorials , QuickStarts

    Introduction

    By now we have discussed the preparations around the project, how to add a DomainService that contains our business logic and combine it with the entity framework. If you have missed one of the previous articles you can find them here:

    Creating applications with .NET RIA Services Part 1 - Introduction

    Creating applications with .NET RIA Services Part 2 - Creating the project

    Creating applications with .NET RIA Services Part 3 - Adding a DomainService class

    As you know from the previous articles in order to demonstrate the features of the .NET RIA Services I am creating the Web Administration Tool from ASP.NET in Silverlight. In this article I am going to create the Manage Users page and add the functionality needed to visualize Data. For that purpose I will need the DataGrid control, the new DataPager control and the DomainDataSource that is a part of the .NET RIA Services framework.

    Here is a link to the live demo at this stage and the source code. Note that they will be updated with each article! ;)

    Adding the DomainDataSource control

    The DomainDataSource control can be found in the Systems.Web.Ria.Controls assembly and we have to declare the proper namespace in order to use it:

    <navigation:Page x:Class="WebAdministrationTool.ManageUsers" 
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
               ...
               xmlns:ria="clr-namespace:System.Windows.Controls;assembly=System.Windows.Ria.Controls"
               ...
               Title="ManageUsers Page">
        <Grid x:Name="LayoutRoot">
            ...
            <ria:DomainDataSource x:Name="UsersDataSource"></ria:DomainDataSource>
            ...
        </Grid>
    </navigation:Page>

    The next step is to configure the DomainDataSource control to work with our DomainService class named UsersManager, which we have created in the previous article. The only thing we have to do is to set the DomainContext property:

    <navigation:Page x:Class="WebAdministrationTool.ManageUsers" 
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
               ... 
               xmlns:ria="clr-namespace:System.Windows.Controls;assembly=System.Windows.Ria.Controls"
               xmlns:local="clr-namespace:WebAdministrationTool"
               ...
               Title="ManageUsers Page">
    <Grid x:Name="LayoutRoot">
        ...
        <ria:DomainDataSource x:Name="UsersDataSource" LoadMethodName="LoadAspnet_Users">
            <ria:DomainDataSource.DomainContext>
                <local:UsersManager />
            </ria:DomainDataSource.DomainContext>
        </ria:DomainDataSource>
        ...
    </Grid>
    </navigation:Page>

    As the UsersManager class can be accessed through the generated code on the client we declare the namespace of our project in the XAML. We also specify the method that the DomainDataSource should use in order to load the data from the data base. Note that on the server our method is named GetAspnet_Users, but on the client it’s LoadAspnet_Users (see in the previous article how to use the DomainService on the client by using the managed code).

    Adding a DataGrid control to the scene

    Now as we have our DomainDataSource control prepared let’s add a Grid and bind them together:

    <data:DataGrid x:Name="UsersGrid" 
                           IsReadOnly="True" 
                           AutoGenerateColumns="False" 
                           HeadersVisibility="None" 
                           GridLinesVisibility="None">
        <data:DataGrid.ItemsSource>
            <Binding ElementName="UsersDataSource" Path="Data" />
        </data:DataGrid.ItemsSource>
        <data:DataGrid.Columns>
            <data:DataGridTextColumn Binding="{Binding UserName}" />
        </data:DataGrid.Columns>
    </data:DataGrid>

    Using the Element-to-Element binding that came with Silverlight 3 we bind the ItemsSource of the DataGrid to the Data property of the DomainDataSource control.

    Now let’s add a row details to our DataGrid, which will give more information about the selected user. First let’s take a look at the GetAspnet_Users of the UsersManager DomainService on the server:

    public IQueryable<aspnet_Users> GetAspnet_Users()
    {
        return this.Context.aspnet_Users;
    }

    It returns the content of the aspnet_Users table. In this table the only information we have is the username. The email, the comment and if the user is active can be found in the aspnet_Membership table and the information about the roles, that the user is in, is located in the aspnet_UsersInRoles table. These two tables are in relation with the aspnet_Users table and the associations between them are defined in the data model, so we can modify the get method in the following way:

    public IQueryable<aspnet_Users> GetAspnet_Users()
    {
        return this.Context.aspnet_Users.OrderBy( "it.UserName" )
                           .Include( "aspnet_Membership" )
                           .Include( "aspnet_UsersInRoles" );
    }

    In the previous article we configured the metadata for the aspnet_Users, so we can now use the following properties on the client:

    internal sealed class aspnet_UsersMetadata
    {
        ...
        [Include]
        public aspnet_Applications aspnet_Applications;
     
        [Include]
        public aspnet_Membership aspnet_Membership;
     
        [Include]
        public EntityCollection<aspnet_UsersInRoles> aspnet_UsersInRoles;
        ...
    }

    When the query is executed they are populated with the proper data. Now back on the client we have the following row details template for the DataGrid:

    <data:DataGrid x:Name="UsersGrid"
                   IsReadOnly="True"
                   AutoGenerateColumns="False"
                   HeadersVisibility="None"
                   GridLinesVisibility="None">
            ...
        <data:DataGrid.RowDetailsTemplate>
            <DataTemplate>
                <Grid>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="Auto" />
                        <ColumnDefinition />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <TextBlock x:Name="IsActiveLabel" Text="Is active:  " FontWeight="Bold" Grid.Column="0" Grid.Row="0" />
                    <TextBlock x:Name="IsActiveBlock" 
    Text
    ="{Binding aspnet_Membership.IsApproved,Converter={StaticResource BooleanConverter}}"
    Grid.Column="1" Grid.Row="0" />
                    <TextBlock x:Name="EmailLabel" Text="E-mail: " FontWeight="Bold" 
    Grid.Column="0" Grid.Row="1" />
                    <TextBlock x:Name="EmailBlock" Text="{Binding aspnet_Membership.Email}" 
    Grid.Column="1" Grid.Row="1" />
                    <TextBlock x:Name="DescriptionLabel" Text="Description: " FontWeight="Bold" 
    Grid.Column="0" Grid.Row="2" />
                    <TextBlock x:Name="DescriptionBlock" Text="{Binding aspnet_Membership.Comment}" 
    Grid.Column="1" Grid.Row="2" />
                </Grid>
            </DataTemplate>
        </data:DataGrid.RowDetailsTemplate>
        ...
    </data:DataGrid>

    That’s it!

    Paging the data

    There is one last thing left to do – to add paging to the DomainDataSource. That can be easily accomplished by using the DataPager control (introduced with Silverlight 3). The control is located in the System.Windows.Controls.Data.DataForm assembly, so once again we have to declare a namespace in our XAML:

    <navigation:Page x:Class="WebAdministrationTool.ManageUsers" 
               xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
               xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
                ...
               xmlns:validation="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Data.DataForm"
                ...
               Title="ManageUsers Page">
        <Grid x:Name="LayoutRoot">
            ...
            <validation:DataPager x:Name="UsersPager"
                                  PageSize="10" 
                                  Source="{Binding Data, ElementName=UsersDataSource}" />
        </Grid>
    </navigation:Page>

    Once bound to the Data property of the DomainDataSource control it handles the paging itself, we just have to set its page size. The most important thing to mention is that the DataPager control can page collections which implement the IPagedCollectionView interface. The Data property is such a collection.

    Also here the LoadSize property of the DomainDataSource control can be found useful. It determines the count of the items to be loaded in the Data property of the control. For example I can set it to 10 and each time the page is changed only 10 items will be loaded. In the common case we set it to a number multiple to the page size. Another option is to set it to the count of the items, if it is known, so all items will be loaded and no other requests to the server will be made.

    Note: The DataPager doesn't work with unsorted collections, because the Skip and Take extension methods, that the control uses, are unavailable for such them. By default the EntityFrameowrk returns unsorted data and that's why I have added an OrderBy to my query. The other way is to sort the data on the client via the DomainDataSource control, but that will be the subject of my next article.

    Conclusion

    In this article I explained some basics about the DomainDataSource, the DataGrid and the DataPager controls. Thanks to them the loading and the visualization of data is not as tough as it was before. In the next article we’ll see how they allow us to easily apply sorting and filtering to the loaded data.

    If you have any questions, I’ll be glad to answer them. :)

    Share


    Comments

    Comments RSS RSS
    • RE: Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource  

      posted by Rob on Apr 04, 2009 01:38
      Is it possible to use .Net RIA Services with Azure Table Storage.
    • RE: Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource  

      posted by Jonathan on May 29, 2009 19:02
      I get an error whenever I try to add the domain datasource to my xaml file:
      http://silverlight.net/forums/p/99299/226646.aspx#226646

      do you have any ideas about this?

    • RE: Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource  

      posted by silverlight man on Jun 20, 2010 12:14

      I get this error when i make a getaspnetUser :

      Problem in mapping fragment starting at lines 67 , 75 :

      Foreign key constraints FK_aspnet_Us_Role from table aspnet_UserInRoles (RoleId) to table aspnetRoles

      Insufficent mapping : foreing key must be mapped to some associationSet etc....

    • RE: Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource  

      posted by anonymous on Jun 21, 2010 09:53

      Your project doesn't work in silverlight 4.0 and RIA 1.0 with visual studio 2010...

       

    • RE: Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource  

      posted by George on Nov 09, 2010 18:12
      Could you convert this project/example to work with silverlight 4 vs2010 ?
    • RE: Creating applications with .NET RIA Services Part 4 - Adding a DomainDataSource  

      posted by Ricky on Dec 01, 2010 09:02
      I wonder if any of the examples/projects shown on www.silverlightshow.net actually work when you TRY to reproduce them on your own machine. It is amazing how there is so much information and examples available, yet not one describes a step by step approach. It is very frustrating to try this and spent hours on searching why something is not working, to then find out on your own that you should have added a reference of which ofcourse no word gets written in the "example".

    Add Comment


         
     
     
       
         

Add Comment

Login to comment:
  *      *       
Login with Facebook

From this series