eFORCE
Blogs Home | Corporate Website
| Home |

Showing Reports by ReportViewer Control and NHibernate

Showing Reports by ReportViewer Control and NHibernate

In one of my Projects I was told to show some data using ReportViewer control and NHibernate. I had no idea how to do it.  Started Googling.... But I was quite surprised there was no such postings, even not found any information whether it is possible or not ! Never mind, started doing it and after completion found it pretty simple. Would like to share it with you.

Step 1:

 I am using a single table, say Customers with the following schema :

Customers

  CustomerID int IDENTITY(1,1) NOT NULL,

  FirstName nvarchar(50) default NULL,

  LastName nvarchar(50) default NULL,

  Address nvarchar(150) default NULL,

  PRIMARY KEY (CustomerID)

The Business Class is:

Customer.cs
namespace NHibernate.Example

{

    public class Customer

    {

        public Customer()

        {

        }

 

        private int id;

        private string firstName;

  private string lastName;

        private string address;

 

        public virtual int Id

        {

            get { return id; }

            set { id = value; }

        }       

 

        public virtual string FirstName

        {

            get { return firstName; }

            set { firstName = value; }

        }

       

        public virtual string LastName

        {

            get { return lastName; }

            set { lastName = value; }

        }

       

        public virtual string Address

        {

            get { return address; }

            set { address = value; }

        }                 

    }

}

And Here is the Mapping file:

Customer.hbm.xml
 <?xmlversion="1.0"encoding="utf-8" ?>
 <hibernate-mappingxmlns="urn:nhibernate-mapping-2.2">
 
 <class name="NHibernate.Example.Customer, NHibernate.Example"
            table="[NHibernate_Test].[dbo].[Customers]">
 
      <id name="Id"column="CustomerID"type="Int32"unsaved-value="0">
      <generatorclass="native" />
      </id>
      <propertyname="FirstName"column="FirstName"type="String" />
      <propertyname="LastName"column="LastName"type="String" />
      <propertyname="Address"column="Address"type="String" />
           
 </class>
 </hibernate-mapping>

Step 2:

We have to create a Typed Dataset in App_Code folder of our Website (or you can have your separate Project Library for DataSet). The data table of this DataSet will contain the fields which we want to show in our Report. Here, I would like to show all the fields of my Customers table. Therefore my Dataset looks like this :

Step 3 :

Create a RDLC file. Arrange the fields just by dragging and dropping the fileds of Dataset which you will find from "Website data Sources" toolbar (to view this toolbar just click the RDLC body, go to the menu "Data" --> "Show Data Sources").

Step 4:

Now the whole environment is ready for coding. Just add a ReportViewer to an aspx page and use the following code and you are done to throw some data on your screen!

using System;
using System.Collections;
using Microsoft.Reporting.WebForms;
using NHibernate;
using NHibernate.Example;
 
public partial class CustomerReport : System.Web.UI.Page
{
    DataSet1 ds = new DataSet1();
    NHibernate.Cfg.Configuration newConfig = new NHibernate.Cfg.Configuration();
    ISessionFactory sFactory;
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!Page.IsPostBack)
        {
            newConfig = newConfig.AddAssembly("NHibernate.Example");
            sFactory = newConfig.BuildSessionFactory();
 
            rvCustomer.LocalReport.ReportPath = "TestReport.rdlc";
            rvCustomer.LocalReport.ReportEmbeddedResource = "ReportViewer.TestReport.rdlc";
            rvCustomer.LocalReport.DataSources.Clear();
 
            ISession session = sFactory.OpenSession();
           
            //get the list of customers using NHibernate
            IList customers = session.CreateCriteria(typeof(Customer)).List();
 
            //populate the typed Dataset
            foreach (Customer customer in customers)
            {
                ds.Customers.AddCustomersRow(customer.Id.ToString(),
                                             customer.FirstName,
                                             customer.LastName,
                                             customer.Address);
            }
           
            rvCustomer.LocalReport.DataSources.Add(
                new ReportDataSource("DataSet1_DataTable1", ds.Customers));
        }
          // data Source name "DataSet1_DataTable1" generally made by DataSet name + "_"
          // + DataTable name of the DataSet
     }
}

Finally the Output :

Run the above page and you will see all the data of Customers table.

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

Hope this information will help somebody somehow !

Print | posted on Monday, May 05, 2008 6:54 AM

Feedback

Gravatar

# re: Showing Reports by ReportViewer Control and NHibernate

Kaushik, here you seem to be creating an extra data-set just to map it to reports. Over a period of time isn’t this supposed to be a maintenance nightmare? This approach seems traditional since you’re basically iterating a list<T>, copying each item to a data-set and then using the data set to create a report. Any other e elegant ways of directly assigning a List<T> to a Report viewer report?
5/5/2008 8:36 AM | rajiv
Gravatar

# re: Showing Reports by ReportViewer Control and NHibernate

Thank you Rajiv for your valuable comments. In case of Dynamic RDLC generation it is possible, but in my case I am not sure. Will try to find out.
5/5/2008 9:04 AM | Koushik
Gravatar

# re: Showing Reports by ReportViewer Control and NHibernate

The title of the post got me interested until I read the last word! NHibernate scares Me, honestly. Thankfully there is Report Viewer involved in this post so that I could take a breath of sigh and read.

As far as my experiences with .rdlc files say, its pretty much strict to the DataTable-nested-Fields schema. If you can quickly open the .rdlc file in any text/xml viewer you will see how it's organized. The content has references to expected DataSets# & Fields along with their expected (strict) names. A small spell mistake in the reportdatasource's name while adding a datasource to the local report (which MUST be same as the DataSet name mentioned in the rdlc xml) and you have a beautiful white screen in front of you.
(# Interesting thing to note is that the rdlc xml terms the expected datatable as DataSet.)

Though as far as Type DataSet is concerned, its ONLY required while Designing a Report File (rdlc). The moment you drag a typed dataset's field to a report UI, the details of the field gets added to the rdlc xml. And you can understand that changing the typed dataset lateron doesn't replicate changes. Typed dataset just helps you with a readymade list of fields from which you can drag drop the ones you need. You can even add your report datasource by editing the rdlc's xml by hand if you are comfortable with its schema, hierarchy & organization and thus give away the type dataset file altogether.

One thing to remember, while binding data to the report datasource, you have to make sure that the bound data follow the exact schema along with the field names as mentioned IN the rdlc's xml. You can even do DataTable dt = new DataTable("DataSet1_DataTable1") and add columns (as expected) and rows to it. Will work wonder! So, in the end it's the rdlc's xml that gets generated & coupled with the supplied datasource.

Couldn't experiment much with rdlc file, hence didn't try binding data other than DataTables. But I am sure there Must be. And just for a ray of hope, there is one interesting node in the rdlc xml named as ObjectDataSourceSelectMethod, tweaking it may bind a List or an Array to a report viewer. Just an innovative thought :-)
5/5/2008 12:38 PM | Rohit Jain
Gravatar

# re: Showing Reports by ReportViewer Control and NHibernate

Thank you Rohit for your suggestion.

Yes it is possible to show data in Report Viewer binding direct with List<T> or an IList.
The method is same. Only you have to do is, just delete the Typed Dataset after making the rdlc XML file. Edit the rdlc in any XML viewer and take the DataSet name(you can take it after renaming too). Suppose DataSet name is "MyDataSet".
In the ReportViewer page get the List is Customers, like:

IList customers = session.CreateCriteria(typeof(Customer)).List();

and after that just do the following:

rvCustomer.LocalReport.DataSources.Add(new ReportDataSource("MyDataSet", customers));

This will bind the DataSource with the Customers List.

N.B: In the RDLC file, the fieldname must be the same with the Business Class properties.
5/8/2008 2:06 AM | Koushik

Post Comment

Title  
Name  
Email
Url
Comment   
Please add 2 and 4 and type the answer here:
Home
Contact
RSS 2.0 Feed
Login
May, 2008 (1)

Powered by: