Tutorial: Entity Data Source Control

Published 18 June 08 02:19 PM | dpblogs 

Last month we announced the beta release of Service Pack 1 for Visual Studio 2008. This release includes the Entity Framework, including a wizard that can be used to generate a model and a graphical model designer. It also includes the EntityDataSourceControl, which lets you bind ASP.NET data bound controls to data from a model.

This tutorial grew out of a project I created during a recent bug-bash of the Entity Framework and the modeling tools. This posting is the first of several in which I will show you how use the Entity Data Model wizard to add an AdventureWorks-based model to a simple Web project. It also shows how to bind data to controls in the web app, both through the EntityDataSource, and by executing queries directly against the entity data model.

Prerequisites
  • Visual Studio 2008
  • The beta release of Visual Studio 2008 Service Pack 1 - available for download here.
  • The AdventureWorks sample DB, which is available in the database samples on CodePlex. I used the version of AdventureWorks that has been updated for SQL Server 2008, but the SQL Server 2005 version should work as well. The AdventureWorksLT database won’t work for the specific tutorial steps as written.
Initial Setup

These are the steps used to create a simple web project which we will use throughout the tutorial. The steps are written to create a C# based Web project as it’s the .NET language with which I’m most comfortable.

  1. Open Visual Studio and create an ASP.NET Web Application project named EDMWorks.
    a. Click File, point to New, and click Project.
    b. Select the ASP.NET Web Application template and change the project name to EDMWorks.
  2. Rename the Default.aspx page to Products.aspx
  3. Add three web pages to the project named ProductDetails.aspx, ProductReview.aspx, and ReadImage.aspx.
    a. In Solution Explorer, right click the project name (EDMWorks), point to Add, and click Add New Item.
    b. Select the Web Form template, and rename it ProductDetails.aspx. Click Add.
    c. Repeat for the 2 remaining web pages.
Use the Designer to add the AdventureWorks model to the Web site
  1. Right click the EDMWorks project and select Add New Item
  2. Select the ADO.NET Entity Data Model template, and name the model AdventureWorksModel.edmx. Click Add.
  3. On the Choose Model Contents page of the wizard, select Generate from database and click Next.
  4. On the Choose Your Data Connection page of the wizard, click New Connection to open the Connection Properties dialog box to generate a connection string for the AdventureWorks database you want to connect to.
  5. In the Save entity connection settings in Web.Config as text box, enter AdventureWorksModelConnection, and click Next.
  6. In the Choose Your Database Objects page of the wizard, select Tables, Views, and Stored Procedures. Use AdventureWorksModel for the namespace. Click Finish.

We won’t use the actual designer for this tutorial, but you can double-click the AdventureWorksModel.edmx file in Solution Explorer to take a look at the model that was generated by the wizard.

Add EntityDataSource controls to the Products.aspx web page

This page allows the user to view details about all the products AdventureWorks sells. We will add four data-bound controls and an EntityDataSource control for each as follows:

 

Data source name Purpose Associated data-bound control
dsCategory Select the ProductCategory entity’s Name and ProductCategoryID properties. DropDownList named ddCategory
dsSubCategory

Based on the category selected in the Category drop down list, select the ProductSubcategory entity’s Name and ProductSubcategoryID properties.

GridView named gvwSubcategories
dsProduct

Display all the products for the subcategory selected in the Subcategories grid view.

GridView named gvwProduct
dsProductDetails Display details in a DetailsView control about the product that is selected in the Products grid view.

DetailsView named dvwProduct
Selected fields are Name, Color, and Price

 

Add the dsCategory data source control
  1. Open the Products.aspx web page in Design view.
  2. Add the four data-bound controls to the page
    a. Drag a DropDownList control from the Toolbox to the designer surface. Rename the control to ddCategory, and change its AutoPostBack property to True.
    b. Drag two GridView controls to the designer surface and rename them gvwSubcategories and gvwProduct.
    c. Drag a DetailsView control to the designer surface and rename it dvwProduct.
  3. Build the project. This is needed to generate the metadata for the model before we can connect the EntityDataSource control to it.
  4. Drag an EntityDataSource control from the Toolbox to the designer surface, next to the ddCategory drop down list.

    NOTE: if the EntityDataSource control is not available in the Data section of your Toolbox, Guy Burstein's blog post on the EntityDataSource control tells how to add it:

    http://blogs.microsoft.co.il/blogs/bursteg/archive/2008/05/12/EntityDataSource-Entity-Data-Source.aspx
  5. Under the EntityDataSource Tasks flyout, click Configure Data SourceedscTutorial_1
    The Configure Data Source wizard launches
  6. On the Configure Object Context page of the wizard, select AdventureWorksModelConnection in both the Named Connection and the DefaultContainerName drop down lists. Click Next.
  7. On the Configure Data Selection page of the wizard, in the EntitySetName drop down list, select ProductCategory. In the Select list box, check ProductCategoryID and Name. Click Finish.

    This configures the selection for the data source, but we also want to add an OrderBy clause to ensure the returned list of categories is ordered by the category’s name, and not its Id.
  8. In the Properties window for the data source control, click the field next to OrderBy and click the ellipsis buttonedscTutorial_2
    This opens the Expression Editor for the data source control.
  9. In the OrderBy Expression text box, enter it.Name. Click OK.
  10. Rename the control to dsCategory.
Bind the dsCategory data source control to the ddCategory drop down list
  1. Click the flyout for the ddCategory drop down list, and under DropDownList Tasks, select Choose Data Source

    The Data Source Configuration Wizard launches
  2. On the Choose a Data Source page of the wizard, select dsCategory in the Select a data source drop down list.
  3. Configure the control to display the Name property in the drop down list, and to use the ProductCategoryID for the list’s value:edscTutorial_3
  4. Click OK to finish binding the data source to the control.

    At this point you can run the Web project to verify that the control is correctly picking up the product categories from the AdventureWorks database:
    edscTutorial_4

Add the dsSubCategory data source control

    This control is hooked to a grid view, and is used to display a product subcategory based on the selection in the ddCategory drop down list.

  1. Drag an EntityDataSource control from the Toolbox to the designer surface. Name the control dsSubCategory.
  2. Under the EntityDataSource Tasks flyout, click Configure Data Source. Use the Configure Data Source wizard to select the ProductSubcategory entity’s ProductSubcategoryID and Name properties.

    For this data source, we need to add a Where clause to filter the selection based on the ProductCategory that was selected in the ddCategory drop down list.

    NOTE: In the beta release of the service pack, you can’t use the expression editor to generate a parameterized clause that is bound to a control’s value. Because of this, we’ll create the Where clause in the .aspx file.
  3. Switch to Source view to edit the Products.aspx file.
  4. Find the code for the dsSubCategory control, and add a Where clause and WhereParamaters, so it looks like the following:

    <asp:EntityDataSource ID="dsSubCategory"runat="server"
      
    ConnectionString
    ="name=AdventureWorksModelConnection"
      
    DefaultContainerName
    ="AdventureWorksModelConnection"
      
    EntitySetName
    ="ProductSubcategory"
      
    Select="it.[ProductSubcategoryID], it.[Name]"Where
    ="it.ProductCategory.ProductCategoryID = @ProductCategoryID">
        <
    WhereParameters
    >
            <
    asp:ControlParameter ControlID
    ="ddCategories"
          
    Type="Int32"Name
    ="ProductCategoryID" />
        </
    WhereParameters
    >
    </
    asp:EntityDataSource>
Bind the dsSubCategory data source control to the Subcategories grid view
  1. Switch back to the Design view of Products.aspx.
  2. Click the flyout for the gvwSubcategories grid view to open the GridView Tasks.
  3. In the GridView Tasks, select the Enable Selection option.
  4. Select dsSubCategory in the Choose Data Source list.
  5. Click Edit Columns to open the Fields dialog box.
  6. Clear the check box for the Auto-generate fields option.
  7. Click the Refresh Schema link. This updates the available fields with the bound fields ProductSubcategoryID and Name from the data source.
  8. Select the Name bound field from the Avaliable fields list, and click Add. This adds the Name field to the Selected fields list.
  9. In the BoundField properties, change the HeaderText property from Name to Subcategories.
  10. In the Selected fields list, click the Select command. Click the button with the blue down arrow to move the Select field to the bottom of the list.
  11. In the CommandField properties, change the value for the SelectText property to [>].
  12. Switch to the Source view , and set the DataKeyNames for the control to ProductSubcategoryID as follows:
<asp:GridView ID="gvwSubcategories" runat="server" 
AutoGenerateColumns="False" DataSourceID="dsSubCategory" 
      DataKeyNames="ProductSubcategoryID">

At this point you can run the Web site to verify that the grid view displays the subcategories
based on the selected category:
edscTutorial_5

Add the dsProduct data source control

This control is hooked to a grid view, and is used to display all products for a given subcategory, based on the selection in the Subcategories grid view

  1. Drag an EntityDataSource control from the Toolbox to the designer surface and name it dsProduct.
  2. Use similar steps to those you took to create the dsSubcategory data source, except this time the you want to select the Product entity’s ProductID and Name properties, and your Where clause should select the Products whose SubcategoryID matches the selection in the Subcategories grid view.

The finished markup code should look something like:

<asp:EntityDataSource ID="dsProduct"runat="server"
  
ConnectionString
="name=AdventureWorksModelConnection"
    
DefaultContainerName
="AdventureWorksModelConnection"
EntitySetName
="Product"
Select="it.[ProductID], it.[Name]"OrderBy
="it.[Name]"
Where
="it.ProductSubcategory.ProductSubcategoryID =
@ProductSubcategoryID">
      <
WhereParameters
>
          <
asp:ControlParameter ControlID
="gvwSubcategories"
Name
="ProductSubcategoryID"
PropertyName="SelectedValue"Type
="Int32"/>
      </
WhereParameters
>
</
asp:EntityDataSource
>

 

Bind the dsProduct data source control to the gvwProduct grid view
  1. Click the flyout for the gvwProduct grid view to open the GridViewTasks.
  2. In the GridView Tasks, select the Enable Paging and Enable Selection options.
  3. In the Choose Data Source list, select dsProduct. 
  4. Click Edit Columns to open the Fields dialog box. 
  5. Clear the check box for the Auto-generate fields option.
  6. Click the Refresh Schema link. This updates the available fields with the bound fields ProductID and Name from the data source. 
  7. Select the Name bound field from the Avaliable fields list, and click Add. This adds the Name field to the Selected fields list. 
  8. In the BoundField properties, change the HeaderText property from Name to Products.
  9. In the Selected fields list, click the Select command. Click the button with the blue down arrow to move the Select field to the bottom of the list. 
  10. In the CommandField properties, change the value for the SelectText property to [>]. Click OK. 
  11. Switch to the Source view , and set the DataKeyNames for the control to ProductID as follows:
<asp:GridView ID="gvwProduct" runat="server" AllowPaging="True" 
AutoGenerateColumns="False" DataSourceID="dsProduct" 
DataKeyNames="ProductID">

At this point you can run the Web site to verify that the grid view displays the products based
on the selected subcategory:

edscTutorial_6

Add the dsProductDetails data source control

This control is hooked to a details view, and is used to display information about the product selected in the Products grid view.

  1. Drag an EntityDataSource control from the Toolbox to the designer surface, and name it dsProductDetails.
  2. Use similar steps to those you took to create the previous data sources, except this time you want to select the Product entity’s ProductID, Name, Color, and ListPrice properties, and your Where clause should select the Product whose ProductID matches the selection in the gvwProducts grid view.

The finished markup code should look something like:

<asp:EntityDataSource ID="dsProductDetails" runat="server" 
ConnectionString="name=AdventureWorksModelConnection" 
DefaultContainerName="AdventureWorksModelConnection"
EntitySetName="Product" 
Select="it.[ProductID], it.[Name], it.[Color], it.[ListPrice]" 
      Where="it.ProductID = @ProductID">
      <WhereParameters>
          <asp:ControlParameter ControlID="gvwProduct" 
Name="ProductID" PropertyName="SelectedValue"
Type="Int32" />
      </WhereParameters>
</asp:EntityDataSource>
Bind the dsProductDetails data source control to the dvwProduct details view
  1. Click the flyout for the dvwProduct details view to open the DetailsViewTasks.
  2. Select dsProductDetails in the Choose Data Source list.
  3. Click Edit Fields to open the Fields dialog box.
  4. Clear the check box for the Auto-generate fields option.
  5. Click the Refresh Schema link. This updates the available fields with the bound fields ProductID, Name, Color, and ListPrice from the data source.
  6. Add the Name, Color, and ListPrice fields to the selected fields. Change the HeaderText properties for the Name and ListPrice fields to Product and Price, respectively.
  7. Select TemplateField in the available fields list, and click Add twice to add two template fields to the selected fields.
  8. Click OK to close the Fields dialog box.

    You can use the ItemTemplate editor, but I find it easier to edit templates directly in the source code
  9. Switch to the Source view to edit the two item templates you just added. Edit the code for your details view so the TemplateFields look like the following:
<asp:TemplateField>
    <ItemTemplate>
        <a href='ProductDetails.aspx?ProductID=<%# Eval("ProductID") %>'>
             [More Details...]</a>
        </ItemTemplate>
    </asp:TemplateField>
<asp:TemplateField>
    <ItemTemplate>
        <a href='ProductReview.aspx?ProductID=<%# Eval("ProductID") %>
&ProductName=<%# Eval("Name") %>'> [Product Reviews...]</
a> </ItemTemplate> </asp:TemplateField>

At this point you can run the Web site to verify that the details view displays the Name, Color, and Price for the correct product:

edscTutorial_7

That’s it for the first post in this tutorial. In later postings, I’ll show how to implement the code for the ProductDetails and ProductReview pages. I’ll also show how to read the images for the selected products using Entity SQL queries executed against the model.

Additional Links:

Guy Burstein has created a screencast about the EntityDataSource control on Channel 9.

 

Eric Dettinger
Software Design Engineer in Test, ADO.NET Entity Framework

Comment Notification

If you would like to receive an email when updates are made to this post, please register here

Subscribe to this post's comments using RSS

Comments

# Pregnant Man &raquo; Tutorial: Entity Data Source Control said on June 18, 2008 8:13 PM:

PingBack from http://wordnew.acne-reveiw.info/?p=154

# Fatih Sahin said on June 19, 2008 4:37 AM:

EntityDataSource has a lot of capabilities which makes binding process very easier, without having to write sql join queries. This is really awesome. However, when do you plan to release EF? I am planning to use it in our new project, SP1 Beta has lots of bugs.

# Carlos said on June 19, 2008 5:09 AM:

EntityDataSource seems to be good for smalish applications that don't have tiers (you have the select queries inside the datasource). What would be ~really~ interesting is if the EntityDataSource was used for the multi-tier-story. For me what this should do is:

- The EntityDataSource should track changes on the UI so that it knows when a entity is dirty, new or deleted. This tracking should work for 1-many relationships.

- The EntityDataSource should give you back the entity ready for you to call your service tier, either through wcf or just as normal referenced assembly.

- In your service layer the context should attach the entity and replay all your changes for you.

This would be really nice!

# Carlos said on June 19, 2008 5:23 AM:

Ah also! Another nice feature would be if the EntityDataSource could have multiple views so that you could use the DataMember property on a gridview for example, this means you can bind one to many relationships with one datasource.

# Hot Topics said on June 20, 2008 10:58 AM:

A walkthrough on using the new EntityDataSource in ASP.NET websites was added to the ADO.NET Team Blog

# Diego Vega said on June 22, 2008 11:24 PM:

Hello Fatih,

I don’t think we have an official date for the final SP1 release (as you know, the EntityDataSource is going to be included in the first service pack for Visual Studio 2008 and .NET Framework 3.5 together with the Entity Framework), but we will announce it here as soon as we are able to. We don't have plans for any interim release.

Hope this answers your question.

# Diego Vega said on June 22, 2008 11:46 PM:

Hello Carlos,

Thanks for your feedback. The EntiyDataSource was designed to provide a simple out-of-the-box experience to people familiar with other DataSources and with some knowledge of EF and Entity-SQL. Support for multi-tier applications the way you describe wasn’t a goal, but rather to enable direct execution of queries against an EDM model easily and in a mostly declarative manner.

There are certain limitations in the design for the first version that we want to remove in future versions. In the meanwhile, for the scenario you describe, it is very likely that the general-purpose ObjectDataSource executing queries on your own service layer will work much better for you.

Your point about supporting multiple views and DataMember is very interesting. We analyzed the possibility during the development, especially as one way to support master-detail with a single DataSource and in general, covering the requirement to do databinding with EntityCollections. That was really late in the cycle and given that other built-in DataSources do not support it, it represented a high risk, so we decided against it for the first version.

Hope this helps,

Diego

# Khaled Hammouda said on June 23, 2008 11:24 PM:

I have tried to follow the tutorial but bumped into a problem when I tried to build the project after adding the EDM from the database.

In particular, I got the following error in the Error List:

"Error 27 The table 'AdventureWorks2008.Production.Document' was referenced by a relationship, but was not found. C:\dev\projects\EdmWorks\EdmWorks\AdventureWorksModel.edmx 0 1 EdmWorks"

Working backward in the output messages, I found those related messages:

"Message 3 The data type 'hierarchyid' is not supported, the column 'DocumentNode' in table 'AdventureWorks2008.Production.Document' was excluded. C:\dev\projects\EdmWorks\EdmWorks\AdventureWorksModel.edmx 0 1 EdmWorks"

"Message 4 The column 'DocumentNode' on the table/view 'AdventureWorks2008.Production.Document' was excluded, and is a key column.  The table/view has been excluded.  Please fix the entity in the schema file, and uncomment. C:\dev\projects\EdmWorks\EdmWorks\AdventureWorksModel.edmx 0 1 EdmWorks"

Any suggest on how to fix this would be appreciated.

Khaled

# Dinesh said on June 25, 2008 9:35 PM:

Hi Diego,

I think that for a next release of your EntityDataSource you should really look into supporting enterprise level solutions, as the entity framework is targeted for bigger applications than to linq to sql. In any realistic enterprise application, there is a real need to separate presentation from business logic and data concerns which necessitates the need for a tiered approach. With a tiered approach, the EntityDataSource is virtually unusable.

Secondly, even if we go with the ObjectDataSource, it does not support change tracking for entities requiring a manual replay process on the service tier. This is cumbersome, error-prone and definitely something that can be 'framework'ed.

Any thoughts?

Regards,

Dinesh

# Roy said on December 9, 2008 9:54 AM:

I am using ADO.NET Entity Data Model template to generate edmx code in Visual Studio 2008. I have selected more than a hundred objects in my database. However, some of the objects are missing in the generated code. Is there a limitation on how many object could be selected? If yes, what is the work around?

# Todd Mera said on March 24, 2009 8:11 PM:

Thanks for the demo.  Very helpful.

I think there is a small error on step 4...

----------------------------------

<WhereParameters>

       <asp:ControlParameter ControlID="ddCategories"

      Type="Int32"Name="ProductCategoryID" />

   </WhereParameters>

----------------------------------

ControlID="ddCategories"

--- Should be ---

ControlID="ddCategory"

Leave a Comment

(required) 
(optional)
(required) 
Page view tracker