asp tutorials, asp.net tutorials, sample code, and Microsoft news from 15Seconds
Data Access  |   Troubleshooting  |   Security  |   Performance  |   ADSI  |   Upload  |   Email  |   Control Building  |   Component Building  |   Forms  |   XML  |   Web Services  |   ASP.NET  |   .NET Features  |   .NET 2.0  |   App Development  |   App Architecture  |   IIS  |   Wireless
 
Pioneering Active Server
 Power Search





Subscribe Now!
Free Newsletter
Reference
News
Articles
Archive
Writers
Code Samples
Components
Tools
FAQ
Feedback
Books
Links
DL Archives
Community
Messageboard
List Servers
Mailing List
WebHosts
Consultants
Tech Jobs
15 Seconds
Home
Site Map
Press
Legal
Privacy Policy
internet.commerce














internet.com
IT
Developer
Internet News
Small Business
Personal Technology

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

HardwareCentral
Compare products, prices, and stores at Hardware Central!

-->
An Introduction to LINQ - Part 3
By Thiru Thangarathinam
Rating: 4 out of 5
Rate this article


  • email this article to a colleague
  • suggest an article



  • download source code
  • In the previous installment of this series on LINQ, you learned the basics of DLINQ and saw how to use it to retrieve data from the database. Specifically it focused on the retreival of relational data for display purposes. This installment will shift gears and focus on the XML aspects of LINQ, known as XLINQ. To start with, you will learn the basics of XLINQ (XML Query extensions of LINQ) and then we'll discuss the steps involved in using DLINQ in conjunction with XLINQ to retrieve, transform, and display data. Along the way, you will also see the ways in which you can convert relational data to hierachical data using XLINQ's functional construction capabilities. Finally you will learn the steps involved in implementing complex data binding with hierarchical data generated through XLINQ.

    Introduction to XLINQ

    XLINQ is a new in-memory XML programming API targeted at querying XML data using the standard query operators supplied with LINQ. XLINQ provides both DOM and XQuery/XPath like functionality in a consistent programming experience across the different LINQ-enabled data access technologies. There are two important characteristics of XLINQ. First, as a member of the LINQ family of technologies, XLINQ provides a consistent query experience for querying XML data. Second, XLINQ exposes DOM functionalities in addition to supporting some of the XPath and XSLT features.

    All of the XLINQ related functionalities are exposed through the classes present in the System.Xml.XLinq namespace. The below table provides an overview of the key classes contained in the System.Xml.XLinq namespace.

    Class Description
    XAttribute Represents an XML attribute
    XComment Represents an XML comment
    XContainer Acts as the base class for the XDocument and XElement classes and provides the core methods for querying XML data
    XDocument Represents an XML document, which acts as a logical container for the XML document
    XElement Represents an XML element in an XML document
    XNode Represents any item in the XML document that can be considered as a node in the XML document
    XProcessingInstruction Represents an XML processing instruction
    XText Represents a text node that is used for creating CDATA sections or working with mixed content

    Now that you have had an overview of the classes, the next section shows a simple example of using the XLINQ classes to create an XML document.

    Simple XLINQ Example

    In this section, you will discuss the creation of a simple XML document using the XML classes of the System.Xml.XLinq namespace. One of the new features of XML creation is the functional construction technique, which lets you create all or part of your XML tree in a single statement. By using functional construction with code indentation, you can visualize the structure of resultant XML, resulting in an increase in developers productivity. Let us look at an example that demonstrates the functional construction feature.

    To start with , create a new Web site named AdvancedLINQ using the LINQ ASP.NET Web site template. Modify the newly created Web page code to look as follows:

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ Import Namespace="System.Xml.XLinq" %>
    <%@ Import Namespace="System.Expressions" %>
    <%@ Import Namespace="System.Query" %>
    <script runat="server">
      void btnCreateAndLoadXml_Click(object sender, EventArgs e)
      {
        XDocument bookStoreXml =
          new XDocument(
            new XDeclaration("1.0", "utf-8", "yes"),
            new XComment("Categories XML Example"),
            new XElement("Categories",
              new XElement("Category",
                new XAttribute("id", "1"),
                new XAttribute("name", "Mountain Bikes"),
                new XElement("Product",
                  new XAttribute("id", "2"),
                  new XAttribute("name", "Bearing Ball")
                ),
                new XElement("Product",
                  new XAttribute("id", "3"),
                  new XAttribute("name", "Mountain-100 Silver, 38")
                )
              )
            )
          );

        string xmlFileName = Server.MapPath("App_Data/Categories.xml");
        bookStoreXml.Save(xmlFileName);
        XElement element = XElement.Load(xmlFileName);
        lblResults.Text = Server.HtmlEncode(element.Xml);
      }
    </script>

    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head runat="server">
      <title>Creating a Simple XML Document using XLINQ</title>
    </head>
    <body>
      <form id="form1" runat="server">
        <div>
          <asp:Button ID="btnCreateAndLoadXml" runat="server"
            Text="Create & Load XML"
            Width="127px" Height="41px"
            OnClick="btnCreateAndLoadXml_Click" />
          <br/>
          <asp:Label runat="server" ID="lblResults" />
        </div>
      </form>
    </body>
    </html>

    To start with, you import the required namespaces including the System.Xml.XLinq namespace that contains the core XLINQ classes.

    In the Click event of the command button, you create an instance of the XDocument object and load it with data using the new functional construction feature of XLINQ. After creating the XML document, you save it to the local drive using the Save() method of the XDocument object passing in the XML file name as an argument. Once the file is saved to the local drive, it is also possible for you to load it back on to the memory. To accomplish this, you invoke the Load() method of the XElement.

    Here is the XML produced by the ASP.NET page when you click on the button.

    <?xml version="1.0" encoding="utf-8" standalone="yes"?>
    <!--Categories XML Example-->
    <Categories>
      <Category id="1" name="Mountain Bikes">
        <Product id="2" name="Bearing Ball" />
        <Product id="3" name="Mountain-100 Silver, 38" />
      </Category>
    </Categories>

    Once you know how to work with the XLINQ classes, it then becomes very easy to use these classes in conjunction with DLINQ for transforming relational data structures into hierachical XML structures, which is the focus for the remainder of this article.

    Using XLINQ with DLINQ

    As shown in Part 2 of this article series, one of the first steps in using DLINQ is to generate the data access classes using the sqlmetal utility. If you install the May 2006 LINQ CTP edition, you can find the sqlmetal utility in the "< Drive_Name>\Program Files\LINQ Preview\Bin" folder. To generate the data access wrapper class for the objects contained in the AdventureWorks database, you use the below command in the command prompt.

    sqlmetal /server:localhost /database:AdventureWorks
      /user:username /password:password /code:AdventureWorks.cs

    Once the AdventureWorks.cs file is created, place that inside the App_Code directory of the Web site.

    Simple XML Data Binding

    This section will demonstrate how to perform data binding with the XmlDataSource control using the XML data. This XML data is generated by transforming relational data from the AdventureWorks database to XML data.

    To the ASP.NET Web site, add a new Web page and modify its code to look as follows.

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Data.DLinq" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ Import Namespace="System.Xml.XLinq" %>
    <%@ Import Namespace="System.Expressions" %>
    <%@ Import Namespace="System.Query" %>
    <%@ Import Namespace="System.Web.Configuration" %>

    <script runat="server">
      void Page_Load(object sender, EventArgs e)
      {
        if (!Page.IsPostBack)
        {
          string connectionString = WebConfigurationManager.ConnectionStrings
            ["AdventureWorks"].ConnectionString;
          SqlConnection connection = new SqlConnection(connectionString);
          AdventureWorks db = new AdventureWorks(connection);
          XElement locations =
            new XElement("Locations",
              from location in db.Production.Location
              select
              new XElement("Location",
                new XAttribute("ID", location.LocationID),
                new XAttribute("Name", location.Name),
                new XAttribute("CostRate", location.CostRate),
                new XAttribute("Availability", location.Availability)
              )
            );
          locationSource.Data = locations.Xml;
          gridLocations.DataSource = locationSource;
          gridLocations.DataBind();
        }
      }
    </script>
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head id="Head1" runat="server">
      <title>Simple Data retrieval using DLinq</title>
    </head>
    <body>
      <form id="form1" runat="server">
        <div>
          <asp:XmlDataSource runat="Server" ID="locationSource"
            XPath="Locations/Location"/>
          <asp:GridView ID="gridLocations" runat="server"
            AutoGenerateColumns="false"
            HeaderStyle-BackColor="blue" HeaderStyle-ForeColor="White">
            <Columns>
              <asp:BoundField HeaderText="ID" DataField="ID"/>
              <asp:BoundField HeaderText="Name" DataField="Name"/>
              <asp:BoundField HeaderText="Cost Rate" DataField="CostRate"/>
              <asp:BoundField HeaderText="Availability"
                DataField="Availability"/>
            </Columns>
          </asp:GridView>
        </div>
      </form>
    </body>
    </html>

    To start with, you retrieve the connection string from the Web.config file and use it to create an SqlConnection object. You then pass the SqlConnection object to the constructor of the AdventureWorks (data access class) class.

    The most important part of the code is where you retrieve the data through the AdventureWorks class and convert that into XML format, all using one line of code.

        XElement locations =
          new XElement("Locations",
            from location in db.Production.Location
            select
            new XElement("Location",
              new XAttribute("ID", location.LocationID),
              new XAttribute("Name", location.Name),
              new XAttribute("CostRate", location.CostRate),
              new XAttribute("Availability", location.Availability)
            )
          );

    As you can see from the above, you can easily mix the data retreival DLINQ query with the functional construction feature of XLINQ.

    You then get the XML representation of the data by invoking the Xml property of the XElement object and assign that as source to the XmlDataSource control.

        locationSource.Data = locations.Xml;

    Finally you set the DataSource of the GridView control to the XmlDataSource control and invoke its DataBind() method.

        gridLocations.DataSource = locationSource;
        gridLocations.DataBind();

    Here is the output produced by the page when navigated through the browser.

    Now that you have looked at a simple example of using DLINQ in conjunction with XLINQ, the next two examples build on this foundation and demonstrate advanced XLINQ queries for implementing data binding with a TreeView control.

    Implementing Data Binding with Hierarchical Data

    The last example discussed the data binding with a GridView control. It is also possible for you to bind the XML data to hierachical data bound controls such as a TreeView control. The below code snippet shows an example of how to accomplish this.

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Data.DLinq" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ Import Namespace="System.Xml.XLinq" %>
    <%@ Import Namespace="System.Expressions" %>
    <%@ Import Namespace="System.Query" %>
    <%@ Import Namespace="System.Web.Configuration" %>

    <script runat="server">
      void Page_Load(object sender, EventArgs e)
      {
        if (!Page.IsPostBack)
        {
          string connectionString = WebConfigurationManager.ConnectionStrings
            ["AdventureWorks"].ConnectionString;
          SqlConnection connection = new SqlConnection(connectionString);
          AdventureWorks db = new AdventureWorks(connection);
          XElement categories =
            new XElement("Categories",
              from category in db.Production.ProductSubcategory
              orderby category.ProductSubcategoryID
              select
              new XElement("Category",
                new XAttribute("ID", category.ProductSubcategoryID),
                new XElement("Details",
                  new XAttribute("Name", category.Name)
                )
              )
            );
          categorySource.Data = categories.Xml;
          categoriesView.DataSource = categorySource;
          categoriesView.DataBind();
        }
      }
    </script>
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head id="Head1" runat="server">
      <title>Simple Data Binding with TreeView</title>
    </head>
    <body>
      <form id="form1" runat="server">
        <div>
          <asp:XmlDataSource runat="Server" ID="categorySource"
            XPath="Categories/Category"/>
          <asp:TreeView ExpandImageUrl="Images/closed.gif"
            CollapseImageUrl="Images/open.gif"
            ID="categoriesView" Runat="server">
            <DataBindings>
              <asp:TreeNodeBinding DataMember="Category" ValueField="ID"
                TextField="ID"/>
              <asp:TreeNodeBinding DataMember="Details" ValueField="Name"
                TextField="Name"/>
            </DataBindings>
          </asp:TreeView>
        </div>
      </form>
    </body>
    </html>

    In this example, you use a TreeView control to display the categories data retrieved from the ProductSubcategory table. For this reason, you create the XML document with the root element <Categories> and multiple child <Category> elements, with each <Category> element consisting of all the details of the category.

      XElement categories =
        new XElement("Categories",
          from category in db.Production.ProductSubcategory
          orderby category.ProductSubcategoryID
          select
          new XElement("Category",
            new XAttribute("ID", category.ProductSubcategoryID),
            new XElement("Details",
              new XAttribute("Name", category.Name)
            )
          )
        );

    You bind the above XML output to the TreeView control, which results in the below output.

    The above screenshot shows all the categories in the ProductSubcategory table from the AdventureWorks database.

    Complex Data Binding using XLINQ

    This section will build on the previous example and discuss how to create a complex XML hierarchy that includes all the categories and the corresponding products (that belong to each of the categories) and display them in a TreeView control. First step is to modify the code that dynamically constructs the XML to also include all the products.

    <%@ Page Language="C#" %>
    <%@ Import Namespace="System.Data.DLinq" %>
    <%@ Import Namespace="System.Data.SqlClient" %>
    <%@ Import Namespace="System.Xml.XLinq" %>
    <%@ Import Namespace="System.Expressions" %>
    <%@ Import Namespace="System.Query" %>
    <%@ Import Namespace="System.Web.Configuration" %>

    <script runat="server">
      void Page_Load(object sender, EventArgs e)
      {
        if (!Page.IsPostBack)
        {
          string connectionString = WebConfigurationManager.ConnectionStrings
            ["AdventureWorks"].ConnectionString;
          SqlConnection connection = new SqlConnection(connectionString);
          AdventureWorks db = new AdventureWorks(connection);
          XElement categories =
            new XElement("Categories",
              from category in db.Production.ProductSubcategory
              orderby category.ProductSubcategoryID
              select
                new XElement("Category",
                  new XAttribute("ID", category.ProductSubcategoryID),
                  new XAttribute("Name", category.Name),
                  new XAttribute("ModifiedDate", category.ModifiedDate),
                  from product in category.Product
                  orderby product.Name
                  select
                    new XElement("Product",
                      new XAttribute("ID", product.ProductID),
                      new XAttribute("Name", product.Name)
                    )
                )
            );
        categorySource.Data = categories.Xml;
        categoriesView.DataSource = categorySource;
        categoriesView.DataBind();
        }
      }
    </script>
    <html xmlns="http://www.w3.org/1999/xhtml" >
    <head id="Head1" runat="server">
      <title>Complex Hierarchical Binding with a TreeView control</title>
    </head>
    <body>
      <form id="form1" runat="server">
        <div>
          <asp:XmlDataSource runat="Server" ID="categorySource"
            XPath="Categories/Category"/>
          <asp:TreeView ExpandImageUrl="Images/closed.gif"
            CollapseImageUrl="Images/open.gif" ID="categoriesView"
            Runat="server">
            <DataBindings>
              <asp:TreeNodeBinding DataMember="Category" ValueField="ID"
                TextField="Name"/>
              <asp:TreeNodeBinding DataMember="Product" ValueField="ID"
                TextField="Name"/>
            </DataBindings>
          </asp:TreeView>
        </div>
      </form>
    </body>
    </html>

    Let us discuss the important lines of code.

    To be able to display the products under their corresponding categories, you need to ensure that the resultant XML document reflects this meaning that each <Category> element should contain all the products (that belong to that category) in the form of one or more <Product> elements. You construct such a hierarchy by nesting the from..in..select statement for the products inside the from..in..select statement for the categories.

      XElement categories =
        new XElement("Categories",
          from category in db.Production.ProductSubcategory
          orderby category.ProductSubcategoryID
          select
            new XElement("Category",
              new XAttribute("ID", category.ProductSubcategoryID),
              new XAttribute("Name", category.Name),
              new XAttribute("ModifiedDate", category.ModifiedDate),
              from product in category.Product
              orderby product.Name
              select
                new XElement("Product",
                  new XAttribute("ID", product.ProductID),
                  new XAttribute("Name", product.Name)
                )
            )
        );

    Once you have the right XML structure, you can then easily bind that to the TreeView control using the same approach as discussed in the previous example. The resultant output is shown in the below screenshot.

    Conclusion

    In this part, we looked at the basics of XLINQ and talked about creating XML data on the fly. Then we looked at how to perform queries using DLINQ for data retreival and transform that output for XML data binding with an XmlDataSource control. Finally you also understood the steps involved in performing complex data binding with a TreeView control for displaying hierachical data.

  • Rate This Article
    Not HelpfulMost Helpful
    1 2 3 4 5
    Other Articles
    Jul 21, 2005 - N-Tier Web Applications using ASP.NET 2.0 and SQL Server 2005 - Part 1
    While the .NET Framework made building ASP.NET applications easier then it had ever been in the past, .NET 2.0 builds on that foundation in order to take things to the next level. This article shows you to how to construct an N-Tier ASP.NET 2.0 Web application by leveraging the new features of ASP.NET 2.0 and SQL Server 2005.
    [Read This Article]  [Top]
    Apr 28, 2005 - New Files and Folders in ASP.NET 2.0
    With the release of ASP.NET 2.0, Microsoft has greatly increased the power of ASP.NET by introducing a suite of new features and functionalities. As part of this release, ASP.NET 2.0 also comes with a host of new special files and folders that are meant to be used to implement a specific functionality. This article examines these new files and folders in detail and provides examples that demonstrate how to utilize them to create ASP.NET 2.0 applications.
    [Read This Article]  [Top]
    Mar 10, 2005 - The DataSet Grows Up in ADO.NET 2.0 - Part 2, Cont'd
    Alex Homer continues his detailed look at the major changes to the DataSet class. In this part, he looks at two features that allow developers to work with data in a more structured and efficient way when using the DataSet with a SQL Server 2005 database server.
    [Read This Article]  [Top]
    Mar 9, 2005 - The DataSet Grows Up in ADO.NET 2.0 - Part 2
    Alex Homer continues his detailed look at the major changes to the DataSet class. In this part, he looks at two features that allow developers to work with data in a more structured and efficient way when using the DataSet with a SQL Server 2005 database server.
    [Read This Article]  [Top]
    Mar 3, 2005 - The DataSet Grows Up in ADO.NET 2.0 - Part 1, Cont'd
    In this article, Alex Homer looks at the changes between the version 1.x and version 2.0 DataSet and their associated classes, showing you how you can take advantage of the new features to improve your applications' capabilities and performance.
    [Read This Article]  [Top]
    Mar 2, 2005 - The DataSet Grows Up in ADO.NET 2.0 - Part 1
    In this article, Alex Homer looks at the changes between the version 1.x and version 2.0 DataSet and their associated classes, showing you how you can take advantage of the new features to improve your applications' capabilities and performance.
    [Read This Article]  [Top]
    Feb 16, 2005 - Writing a Custom Membership Provider for the Login Control in ASP.NET 2.0
    In ASP.NET 2.0 and Visual Studio 2005, you can quickly program custom authentication pages with the provided Membership Login controls. In this article, Dina Fleet Berry examines the steps involved in using the Login control with a custom SQL Server membership database.
    [Read This Article]  [Top]
    Dec 29, 2004 - ClickOnce Deployment in .NET Framework 2.0
    In this article, Thiru Thangarathinam examines .NET 2.0's new ClickOnce deployment technology that is designed to ease deployment of Windows forms applications. This new technology not only provides an easy application installation mechanism, it also eases deployment of upgrades to existing applications.
    [Read This Article]  [Top]
    Dec 15, 2004 - A Sneak Peek at ASP.NET 2.0's Administrative Tools
    With ASP.NET 2.0, Microsoft has made great strides in increasing developer productivity and has made implementing previously complex solutions relatively easy. Where this version of ASP.NET really shines, however, is in its new administrative tools that allow developers to spend less time managing the configuration of the servers and software and more time developing great code.
    [Read This Article]  [Top]
    Nov 17, 2004 - The ASP.NET 2.0 TreeView Control
    Thiru Thangarathinam introduces ASP.NET 2.0's new TreeView control which provides a seamless way to consume and display information from hierarchical data sources. The article discusses this new control in depth and explains how to use this feature rich control in your ASP.NET applications.
    [Read This Article]  [Top]
    Mailing List
    Want to receive email when the next article is published? Just Click Here to sign up.

    Support the Active Server Industry