Guy Burstein's Blog

All about the newest tools and technologies from Microsoft

News

Guy Burstein
Work:
Microsoft Israel, 2 Hapnina st', Raanana
Israel
Email:
Or, use this form.
Guy Burstein The Bu

Disclaimer
Postings are provided 'As Is' with no warranties and confer no rights.

Guy Burstein LinkedIn Profile

TwitterCounter for @bursteg

The Bu

Links

Articles

Blogs I Read

How to: Build an N-Tier application with WCF and DataSets in Visual Studio 2008

How to: Build an N-Tier application with WCF and DataSets in Visual Studio 2008

We've known ADO.Net DataSets since the day we started developing data centric applications with the .Net Framework. In the early days of Visual Studio 2003 we have designed DataSets using the XSD designer and had to program the Data Access Layer ourselves. Visual Studio 2008 brings many enhancements to DataSets, which help us to create data centric applications easier than ever. This post is a step by step guide for building an N-Tier application with WCF and DataSets in Visual Studio 2008 that shows all the new enhancements throughout it.

You can download a sample project that is the result of this guide (Download here).

Note: For this guide I am using the Blog Database Schema I published some time ago. Make sure to download the script and create the sample database.

Creating the Data Access Layer

WCF and DataSets Visual Studio 2008 VS20081. Create a new Solution in Visual Studio 2008. Click File-> New Project. In the Project Types tree, expand the Other Project Types node and select a Blank Solution and enter a name for your solution.

2. Create a new Class Library for the Data Access Layer. Note that the new project has a reference to a new assembly that is part of the .Net Framework 3.5 called System.Data.DataSetExtensions, that contains the new enhancements that this guide walks through.

3. Add a new DataSet to the Data Access project - this adds the related files and opens the DataSet Designer. From the Server Explorer, drag the tables of the Blog database to the designer. This creates the appropriate DataTables and their related TableAdapters.

WCF and DataSets Visual Studio 2008 VS2008

In Visual Studio 2005, when the TableAdapters were first introduced, they were generated in the same project as the DataSet class itself. In N-Tier applications, where both server side projects and client side projects had a reference to the DataSets project, we got a situation where the client application had the Data Access layer classes and could use it. This caused many customers to delete the TableAdapters from the DataSet Designer and not use them at all! In Visual Studio 2008, we can separate the generated Dataset class to another project.

WCF and DataSets Visual Studio 2008 VS20084. Separate the Typed DataSet generated code to another project. Create another Class Library for the Business Entities. In the DataSet Designer, display the properties of the DataSet, and select the DataSet Project to be the new project you have just created for the business entities.

This creates the generated code for the DataSet and other business entities in a new file in the selected project.

WCF and DataSets Visual Studio 2008 VS2008

5. Implement the Data Access Logic for getting a blog row. In the DataSet Designer, right click the BlogsTableAdapter and create a new Query. This starts the TableAdapter Query Configuration Wizard that lets you create a new query using an SQL statement or a stored procedure. Select the Use SQL Statement option, click Next, and choose the SELECT which returns rows option. In the SQL Editor, use the following SQL Statement:

WCF and DataSets Visual Studio 2008 VS2008SELECT BlogID, BlogName, Owner
FROM dbo.Blogs
WHERE BlogID = @BlogID

Click Next to choose the methods to generate. the TableAdapter Query Configuration Wizard creates 2 method for each query: GetDataByXXX that returns a new DataTable with the results of the query, and FillDataByXXX that takes an exiting DataTable (that may contain data from previous work) and inserts the query results to it. In this Wizard Step, complete the names of the methods to be GetDataByBlogID and FillDataByBlogID. Click Finish.

After creating the new query, you can preview it's data to make sure that the SQL statement is correct. Right click the new query method in the DataSet Designer and Preview the Data.

This will open the Preview Data Dialog where you should supply the value for the @BlogID parameter and can preview the query results for that value. Use the value bursteg to make sure you receive a single blog row.

WCF and DataSets Visual Studio 2008 VS2008

6. Implement the Data Access Logic for getting the blog posts. Repeat the last step instructions in order to create a new query for the PostsTableAdapter. This query should use the following statement to select the Posts Rows according to a blog ID:

SELECT PostID, BlogID, Title, Body, PublishDate
FROM dbo.Posts
WHERE BlogID = @BlogID

Exposing a Windows Communication Foundation (WCF) Service

7. Create a new Class Library for the Service Contracts. The Service Contract is actually an interface that defines the operations that the service exposes, and the data that goes in and out from it.

WCF and DataSets Visual Studio 2008 VS20088. Add a reference to the System.ServiceModel.dll. This assembly contains the Windows Communication Foundation (WCF) libraries required for exposing the service. Also, add a reference to the Business Entities project that contains the DataSet definition, so the service operations can receive or return an instance of that DataSet.

9. Create an Interface for the Service Contract. This interface should be decorated with the ServiceContract attribute above it, and each method should define the ServiceOperation attribute. In this guide, we'll have two operations - GetBlogPosts takes a blog id and returns a DataSet that contains the Blog Posts, and UpdatePosts takes a DataSet with updated / deleted / added posts and applies the changes back to the database.

[ServiceContract]

public interface IBlogService

{

    [OperationContract]

    BlogDataSet GetBlogPosts(string blogID);

    [OperationContract]

    void UpdatePosts(BlogDataSet dsBlog);

}

10. Create a new WCF Service. Add a new Web Site to the solution, and in the Add New Web Site Dialog, select the WCF Service template. This library contains the Service Implementation and exposes the service via HTTP using IIS or a local file system web server.

WCF and DataSets Visual Studio 2008 VS200811. Add references to all 3 projects you have created earlier - the Service Contract project contains the interface that the service implementation class should implement. The Business Entities project contains the DataSet definition that the implementation uses, and of course the Data Access project that is required to perform the data access. Adding those references will copy the dll's to the Bin directory of the WCF Service.

12. Remove the default Service Implementation. Notice that by default, the WCF Service project template creates the Service Contract and the Service Implementation classes with sample code in them under the App_Code directory of the WCF Service. In this guide, we will not be using any of this sample code, so we'll start by deleting the files IService.cs and Service.cs.

13. Create the Service Implementation. Under the App_Code directory, create a new class for the Service Implementation. The Service Implementation is actually a class the implements the Service Contract and performs the logic of the service, such as accessing the database, data validation and other business logic. Let the new class implement the Service Contract.

public class BlogService : IBlogService

{

    public BlogDataSet GetBlogPosts(string blogID)

    {

        throw new NotImplementedException();

    }

    public void UpdatePosts(BlogDataSet dsBlog)

    {

        throw new NotImplementedException();

    }

}

14. Implement the Service Operations that returns the blog posts of a blog. As an implementation for the GetBlogPosts method, create a new instance of BlogDataSet. Then, create an instance of BlogsTableAdapter and use the FillDataByBlogID method to get the blog row. Very similarly, get that blog's posts using the PostsTableAdapter. Finally, return the DataSet with the data.

public BlogDataSet GetBlogPosts(string blogID)

{

    BlogDataSet dsBlog = new BlogDataSet();

    BlogsTableAdapter blogsAdapter = new BlogsTableAdapter();

    blogsAdapter.FillByBlogID(dsBlog.Blogs, blogID);

    PostsTableAdapter postsAdapter = new PostsTableAdapter();

    postsAdapter.FillByBlogID(dsBlog.Posts, blogID);

    return dsBlog;

}

15. Implement the Service Operations that updates the changes made to the BlogDataSet back to the database using the TableAdapterManager. The TableAdapterManager is a new enhancement in Visual Studio 2008 that takes care of the hierarchic updates from a specific Dataset. When the TableAdapterManager code is generated, it looks on the relations between the DataTables in the DataSet, and decides which rows should be added before which, and which rows should be deleted before which. Before Visual Studio 2008, this logic was performed by the application developer and contained logic that was very similar among many applications. In Visual Studio 2008, this logic is being done using the TableAdapterManager.

As an implementation for this method, create a new instance of the TableAdapterManager, and set its properties with the related TableAdapters. In order to perform the actual update, use the method UpdateAll and pass the DataSet as the parameter.

public void UpdatePosts(BlogDataSet dsBlog)

{

    TableAdapterManager updateManager = new TableAdapterManager();

    updateManager.BlogsTableAdapter = new BlogsTableAdapter();

    updateManager.PostsTableAdapter = new PostsTableAdapter();

    updateManager.UpdateAll(dsBlog);

}

16. Expose the BlogService as a WCF Service. Creating a WCF Service as a Web Site using IIS of a local file system web server, creates a .svc file that defines the name of the Service Implementation class and when its code behind is located. Edit the Service.svc file in the WCF Service project, change the value in the Service attribute to "BlogService" and the name of the CodeBehind file to "~/App_Code/BlogService.cs". When done, the Service.svc should look like:

<%@ ServiceHost Language="C#" Debug="true" Service="BlogService" CodeBehind="~/App_Code/BlogService.cs" %>

17. Configure the WCF Service. The WCF Service configuration is located in the web.config file in the WCF Service project, and contains the information that the web server requires in order to host and expose it. Right Click the web.config file, and choose Edit WCF Configuration. This opens the WCF Service Configuration Editor and lets you edit the configuration in a very convenient way.

WCF and DataSets Visual Studio 2008 VS2008As I mentioned earlier, the WCF Service project template creates a sample WCF Service and configures it. Since we are not using the sample service in this guide, we have to change the configuration to work with our service. To do so, make the following changes in the configuration editor:

  • Under the Services Node, select the Service Node, and in the properties pane, rename the service to be  BlogService.
  • Under the BlogService Node, Under the Endpoints Node, click the first endpoint, and choose the IBlogsService interface. To locate this interface, click the ... button the in the contract property, navigate to the Bin directory, click the Contracts project and select the contract.

When finished, save the changes, and close the WCF Configuration Editor.

To make sure the service is configured well, right click the Service.svc file, and choose View in Browser. The browser should navigate to the .svc file and you should see a web page that like like this one:

WCF and DataSets Visual Studio 2008 VS2008WCF and DataSets Visual Studio 2008 VS2008

Building a Client Application

WCF and DataSets Visual Studio 2008 VS200818. Create a new Windows Forms application as the client application, and add references to the Business Entities project and the Service Contract Project.

19. Create the client side proxy for the WCF Service. Right click the Client Application project, and add a Service Reference. In the Add Service Reference Dialog, click Discover to find the service we have created earlier. Type the name of reference and click the OK.

WCF and DataSets Visual Studio 2008 VS2008 

This creates a proxy class in the client application, and the relevant configuration sections. This makes the consumption of the WCF Service very easy. If you take a look at the generated code (Show all files and look for the Reference.cs file ), you should see that the definition of the DataSet itself and the Service Contract were not generated again. This is because we have referenced their assemblies and the generator used the original definition.

WCF and DataSets Visual Studio 2008 VS200820. Show the blog details. Go to the Windows Forms designer to edit the form in the client application. Display the Data Sources Pane (Data -> Show Data Sources), expand the DataSet Node and from the drop down list of the Blogs DataTable, select Details. Also, expand the Blogs node, and choose Label as the control for the field BlogID.

Select the Blogs Node and drag it onto the form. This creates the appropriate controls for the blog details, and the additional navigation toolbar.

21. Display the blog posts. From the Data Sources Window, drag the list of Posts to the form, and create a DataGridView control. This grid will display the posts of the current blog.

WCF and DataSets Visual Studio 2008 VS2008

22. Get the Data from the WCF Service. Double click the Form to go to the Load event handler. In this handler, create a new instance of the proxy, and call the GetBlogPosts operation. Assign the returned DataSet to the binding source of the blogs table.

private void ClientApplication_Load(object sender, EventArgs e)

{

    BlogServiceClient proxy = new BlogServiceClient();

    this.blogDataSet = proxy.GetBlogPosts("bursteg");

    this.blogsBindingSource.DataSource = this.blogDataSet;

}

Run the application, and make sure you receive the details of the blog you requested, and its posts.

23. Add the support for updates. In the Form Designer, select the Save button in the navigation toolbar which is disabled by default. In the properties pane, set the Enabled property of this button to True, and double click it to create the event handler. In the handler method, create an instance of the proxy, and call the UpdatePosts method.

private void blogsBindingNavigatorSaveItem_Click(object sender, EventArgs e)

{

    this.blogsBindingSource.EndEdit();

    this.postsBindingSource.EndEdit();

    BlogServiceClient proxy = new BlogServiceClient();

    proxy.UpdatePosts(this.blogDataSet);

}

 

Run the application and perform changes to the blog details, add and remove posts, and then click save.

You can download a sample project that is the result of this guide (Download here).

Conclusion

Building an N-Tier data centric application is easier than ever with WCF and DataSets in Visual Studio 2008. The application developer productivity is increasing, the amount of code to write, test and maintain is decreasing, and the results are much better!

Enjoy!

Comments

No Comments