Working with ADO.NET Datasets and .NET Objects using Crystal Reports and ASP.NET 2.0

This is the third article in a series focusing on programming with Crystal Reports with ASP.NET 2.0. In this article, we will focus on working with Crystal Reports with data sources that include ADO.NET datasets and .NET objects.

Contributed by
Rating: 4 stars4 stars4 stars4 stars4 stars / 23
August 06, 2007
Rate this Article:
MEH MEH++


SEARCH ASP FREE
TOOLS YOU CAN USE

advertisement

A downloadable zip file is available for this article.

If you are new to Crystal report programming, I strongly suggest that you go through the following articles:

Programming Crystal Reports with ASP.NET 2.0

Working with Parameters with Crystal Reports and ASP.NET 2.0

This article uses and enhances the solution (source code) provided at the above links. 

If you are new to OOP-based database applications in Visual Basic 2005, I suggest that you go through the following article:

Implementing OOP to Develop Database-Oriented Applications using VB.NET 2005

The entire solution (source code) for this article is available as a free download (in the form of a zip). The source code in this article has been developed using Microsoft Visual Studio 2005 Professional Edition on Microsoft Windows XP Professional Edition with Microsoft SQL Server 2005 Express Edition.  I used the same version of Crystal Reports which comes with Visual Studio 2005 Professional Edition.  I didn't really test any of the code in any other tools/IDEs/servers/editions/versions. If you have any problems, please feel free to post in the discussion area.

Adding a strongly typed dataset to the project: designer

Before proceeding further, open the "SampleWebSite01" website (available as a download through the first article in this series) and add a new dataset as follows:

  • Using the "Solution Explorer," right click on the project name (SampleWebSite01) and click "Add New Item."
  • In the templates, select "Dataset," provide "Orders.xsd" as the "Name" and click on "Add."


  • Click "Yes" when it asks for confirmation of placing the dataset in "App_Code" folder.
  • When it opens the TableAdapter Configuration Wizard, cancel it.
  • Using ToolBox, select DataTable.


  • Place a new DataTable on the designer and rename DataTable to "Orders."
  • Right click on the "Orders" datatable, go to Add -> Column and give the column name as "OrderID"


  • Similarly, add OrderDate, CustomerID and EmployeeID.
  • Using the Properties window, modify the data types of the columns respectively.

Adding a strongly typed dataset to the project: designer code

Once the designing is finished, right click on the designer and go to "View Code."  Make the necessary changes so that the code looks similar to the following:

<?xml version="1.0" encoding="utf-8"?>

<xs:schema id="Orders" targetNamespace="http://tempuri.org/Orders.xsd" xmlns:mstns="http://tempuri.org/Orders.xsd" xmlns="http://tempuri.org/Orders.xsd" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata" xmlns:msprop="urn:schemas-microsoft-com:xml-msprop" attributeFormDefault="qualified" elementFormDefault="qualified">

  <xs:annotation>

    <xs:appinfo source="urn:schemas-microsoft-com:xml-msdatasource">

      <DataSource DefaultConnectionIndex="0" FunctionsComponentName="QueriesTableAdapter" Modifier="AutoLayout, AnsiClass, Class, Public" SchemaSerializationMode="IncludeSchema" xmlns="urn:schemas-microsoft-com:xml-msdatasource">

        <Connections>

        </Connections>

        <Tables>

        </Tables>

        <Sources>

        </Sources>

      </DataSource>

    </xs:appinfo>

  </xs:annotation>

  <xs:element name="Orders" msdata:IsDataSet="true" msdata:UseCurrentLocale="true" msprop:Generator_UserDSName="Orders" msprop:Generator_DataSetName="Orders">

    <xs:complexType>

      <xs:choice minOccurs="0" maxOccurs="unbounded">

        <xs:element name="Orders" msprop:Generator_UserTableName="Orders" msprop:Generator_RowDeletedName="OrdersRowDeleted" msprop:Generator_TableClassName="OrdersDataTable" msprop:Generator_RowChangedName="OrdersRowChanged" msprop:Generator_RowClassName="OrdersRow" msprop:Generator_RowChangingName="OrdersRowChanging" msprop:Generator_RowEvArgName="OrdersRowChangeEvent" msprop:Generator_RowEvHandlerName="OrdersRowChangeEventHandler" msprop:Generator_TablePropName="_Orders" msprop:Generator_TableVarName="tableOrders" msprop:Generator_RowDeletingName="OrdersRowDeleting">

          <xs:complexType>

            <xs:sequence>

              <xs:element name="OrderID" msprop:Generator_UserColumnName="OrderID" msprop:Generator_ColumnPropNameInRow="OrderID" msprop:Generator_ColumnVarNameInTable="columnOrderID" msprop:Generator_ColumnPropNameInTable="OrderIDColumn" type="xs:int" minOccurs="0" />

              <xs:element name="OrderDate" msprop:Generator_UserColumnName="OrderDate" msprop:Generator_ColumnPropNameInRow="OrderDate" msprop:Generator_ColumnVarNameInTable="columnOrderDate" msprop:Generator_ColumnPropNameInTable="OrderDateColumn" type="xs:dateTime" minOccurs="0" />

              <xs:element name="CustomerID" msprop:Generator_UserColumnName="CustomerID" msprop:Generator_ColumnPropNameInRow="CustomerID" msprop:Generator_ColumnVarNameInTable="columnCustomerID" msprop:Generator_ColumnPropNameInTable="CustomerIDColumn" type="xs:string" minOccurs="0" />

              <xs:element name="EmployeeID" msprop:Generator_UserColumnName="EmployeeID" msprop:Generator_ColumnPropNameInRow="EmployeeID" msprop:Generator_ColumnVarNameInTable="columnEmployeeID" msprop:Generator_ColumnPropNameInTable="EmployeeIDColumn" type="xs:short" minOccurs="0" />

            </xs:sequence>

          </xs:complexType>

        </xs:element>

      </xs:choice>

    </xs:complexType>

  </xs:element>

</xs:schema>

Adding a Crystal Report with data source as a strongly typed dataset

Add a new Crystal Report (named "DatasetDemo01.rpt") and select "Standard report" as the expert wizard.  When choosing the data, select "Orders" in ADO.NET Dataset and click "Next."

In the fields screen, select all available fields to "fields to display."

Click "Next" and finally click "Finish."

Report Designer gets opened  and you can format it according to your requirements.

Binding the Crystal Report with a strongly typed dataset

Once the dataset and Crystal reports are created, add a new web form (DatasetDemo01.aspx) to the project, and then drag and drop a button and CrystalReportViewer Control.

Make sure that the source behind looks like the following:

<%@ Page Language="VB" AutoEventWireup="false" CodeFile="DatasetDemo01.aspx.vb" Inherits="DatasetDemo01" %>

 

<%@ Register Assembly="CrystalDecisions.Web, Version=10.2.3600.0, Culture=neutral, PublicKeyToken=692fbea5521e1304"

  Namespace="CrystalDecisions.Web" TagPrefix="CR" %>

 

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

 

<html xmlns="http://www.w3.org/1999/xhtml" >

<head runat="server">

    <title>Untitled Page</title>

</head>

<body>

    <form id="form1" runat="server">

    <div>

      <asp:Button ID="Button1" runat="server" Text="Button" />

      <CR:CrystalReportViewer ID="CrystalReportViewer1" runat="server" AutoDataBind="true" />

    </div>

    </form>

</body>

</html>

In the code behind, copy the following code:

Imports CrystalDecisions.Shared

Imports CrystalDecisions.CrystalReports.Engine

Imports System.Data.SqlClient

Imports System.Data

 

Partial Class DatasetDemo01

    Inherits System.Web.UI.Page

 

  Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

    CrystalReportViewer1_Navigate(Nothing, Nothing)

  End Sub

 

  Protected Sub CrystalReportViewer1_Navigate(ByVal source As Object, ByVal e As CrystalDecisions.Web.NavigateEventArgs) Handles CrystalReportViewer1.Navigate

    Dim dt As New Orders.OrdersDataTable

    Dim ad As New SqlDataAdapter("SELECT TOP 200 OrderID, OrderDate, CustomerID, EmployeeID FROM orders", "Data Source=.sqlexpress;initial catalog=Northwind;user id=sa; password=eXpress2005")

    ad.Fill(dt)

    Dim rep As New ReportDocument

    rep.Load(Server.MapPath("DatasetDemo01.rpt"))

    rep.SetDataSource(CType(dt, DataTable))

    Me.CrystalReportViewer1.ReportSource = rep

    Me.CrystalReportViewer1.DataBind()

  End Sub

End Class

You may have to modify the connection string so that it connects to your server.  Finally, set the start page as DatasetDemo01.aspx, execute the application and hit the button to view the report.

.NET objects as data sources to Crystal Reports: adding an entity class

In previous sections, a strongly typed dataset is created (using Visual Studio Designer) and finally assigned as the data source to Crystal Reports. Now, we will start working on only custom classes (acting as .NET Objects) and assign them as a data source to Crystal Reports.

Close the previous project and create a new website. Using the "Solution Explorer," add a new class named "Order.vb." This class simply works as an entity class holding a single row of the Orders table.  For our demonstration, I took only four fields into consideration.  The code for the "Order" class is as follows:

Imports Microsoft.VisualBasic

 

Public Class Order

  Private _OrderID As Int32

  Private _OrderDate As Date

  Private _CustomerID As String

  Private _EmployeeID As String

 

  Public Property OrderID() As Int32

    Get

      Return _OrderID

    End Get

    Set(ByVal value As Int32)

      _OrderID = value

    End Set

  End Property

 

  Public Property OrderDate() As Date

    Get

      Return _OrderDate

    End Get

    Set(ByVal value As Date)

      _OrderDate = value

    End Set

  End Property

 

  Public Property CustomerID() As String

    Get

      Return _CustomerID

    End Get

    Set(ByVal value As String)

      _CustomerID = value

    End Set

  End Property

 

  Public Property EmployeeID() As String

    Get

      Return _EmployeeID

    End Get

    Set(ByVal value As String)

      _EmployeeID = value

    End Set

  End Property

 

  Public Sub New(ByVal oID As String, ByVal oDate As Date, ByVal oCustomerID As String, ByVal oEmployeeID As String)

    _OrderID = oID

    _OrderDate = oDate

    _CustomerID = oCustomerID

    _EmployeeID = oEmployeeID

  End Sub

 

End Class

.NET objects as data sources to Crystal Reports: adding a collection class

In previous section, we added a class which holds only one row of information from the "Orders" table (but with few fields).  Now, we are adding one more class to hold a set of rows from the "Orders" table based on the "Order" entity class.  This class must be named "Orders.vb" and must inherit from the "CollectionBase" class (part of the .NET Framework Class Library).

Add a new class named "Orders.vb" and copy the following code:

Imports Microsoft.VisualBasic

 

Public Class Orders

  Inherits CollectionBase

 

  Public Sub add(ByVal e As Order)

    List.Add(e)

  End Sub

 

  Public Sub delete(ByVal e As Order)

    List.Remove(e)

  End Sub

 

  Public Sub delete(ByVal index As Integer)

    If index < 0 Or index > List.Count - 1 Then

      Throw New Exception("Invalid index to remove")

    End If

    List.RemoveAt(index)

  End Sub

 

  Default Public Overridable ReadOnly Property Item(ByVal index As Integer) As Order

    Get

      Return CType(Me.List(index), Order)

    End Get

  End Property

 

End Class

It is basically a collection class which holds a group of objects related to the "Order" class.

.NET objects as data sources to Crystal Reports: adding and binding a crystal report

Once the classes are complete, add a new crystal report to the web site (Sample01.rpt) and select the "Order" class available under ".NET Objects" (Fig 07).

Add it as selected table and click next, add all fields and finally click finish. Report Designer opens with all the fields and you can format the report according to your requirements.

Add a new web form (Sample01.aspx) and drag a button and CrystalReportViewer control onto the web form.  In the code behind, copy the following code:

Imports System.Data

Imports System.Data.SqlClient

Imports CrystalDecisions.Shared

Imports CrystalDecisions.CrystalReports.Engine

 

Partial Class Sample01

    Inherits System.Web.UI.Page

 

  Public Shared Function getList() As Orders

    Dim dt As New DataTable

    Dim ad As New SqlDataAdapter("SELECT TOP 200 OrderID, OrderDate, CustomerID, EmployeeID FROM orders", "Data Source=.sqlexpress;initial catalog=Northwind;user id=sa; password=eXpress2005")

    ad.Fill(dt)

    Dim colOrd As New Orders

    For Each dr As DataRow In dt.Rows

      colOrd.add(New Order(dr("OrderID"), dr("OrderDate"), dr("CustomerID"), dr("EmployeeID")))

    Next

    Return colOrd

  End Function

 

 

  Protected Sub CrystalReportViewer1_Navigate(ByVal source As Object, ByVal e As CrystalDecisions.Web.NavigateEventArgs) Handles CrystalReportViewer1.Navigate

    Dim rep As New ReportDocument

    rep.Load(Server.MapPath("Sample01.rpt"))

    rep.SetDataSource(getList())

    Me.CrystalReportViewer1.ReportSource = rep

    Me.CrystalReportViewer1.DataBind()

  End Sub

 

  Protected Sub Button1_Click(ByVal sender As Object, ByVal e As System.EventArgs) Handles Button1.Click

    CrystalReportViewer1_Navigate(Nothing, Nothing)

  End Sub

End Class

Finally, execute the application and hit the button to view the report.

Of all of the above code, the following is the most important part to understand:

Dim colOrd As New Orders

    For Each dr As DataRow In dt.Rows

      colOrd.add(New Order(dr("OrderID"), dr("OrderDate"), dr("CustomerID"), dr("EmployeeID")))

    Next

Once the DataAdapter gives the datatable, I am converting the datatable to "Orders" collection by creating an "Order" object for each row available.  Once the collection is populated, we assign the same as the data source to the Crystal Report.

I hope you enjoyed the article and any suggestions, bugs, errors, enhancements etc. are highly appreciated at http://jagchat.spaces.live.com

blog comments powered by Disqus
ASP.NET ARTICLES

- Implementing ASP.NET 4.0 Page.MetaDescriptio...
- ASP.Net Development Tips
- Intro to Sessions in ASP.Net
- Google Maps API Introduction in ASP.NET usin...
- Creating an ASP.NET 3.5 Gridview Image Galle...
- Encrypt QueryString in ASP.NET 3.5 using VB....
- ASP.NET 3.5 Drop Down List Controls
- Connect to Access Database with ASP.Net
- Secure Audio Streaming with ASP.Net and Flash
- Dynamic Sitemap and Navigation in ASP.Net
- Implement Gzip and Deflate Compression in AS...
- Run ASP.Net in Ubuntu with Apache
- ASP.Net Mono Website Contact Forms
- ASP.Net URL Rewriting Methods
- Murach`s ASP.NET 4 Web Programming with C# 2...

ASP Web Hosting ASP.Net Web Hosting Windows Web Hosting
ASP Free Forums 
 RSS  Tutorials RSS
 RSS  Forums RSS
 RSS  All Feeds
Site Map 
Request Media Kit
Write For Us Get Paid 
Weekly Newsletter
 
Developer Updates  
Free Website Content 
Privacy Policy 
Support 


© 2003-2012 by Developer Shed. All rights reserved. DS Cluster 8 - Follow our Sitemap
Most Popular Topics
All ASP.Net Tutorials