Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / database / SQL-Server

CrystalReports Push Model with .NET

0.00/5 (No votes)
29 Apr 2009CPOL3 min read 18.6K  
How to make custom datasource for CrystalReports engine using push model and .NET

Introduction

I couldn't find a proper description of how to use CrystalReports push model in VS2005 or anywhere else, so everything that was found during three weeks of struggle is in this article.

Background

CrystalReports supports two data models: push and pull. The second one is quite simple: you define a connection string during design time and CRE (CrystalReports Engine) uses it to generate a report based on your template.

One can also provide custom connection string before running the report, but anyway CRE works with tables directly.

But what if there is a requirement to utilize stored procedures instead of tables and to cache some data beforehand or to use a datasource unknown to CRE? Then push model should go.

Unfortunately, there is (or was) very little information on how to actually implement these push mechanisms especially for CRE for .NET apart from a good and simple example of what to do in VS2005 of how to create a report with push model, but without any custom data adapters: "Creating Crystal Reports using C# with Datasets". However in my case, the report was quite complex and should have remained intact and the solution proposed in the article just didn't fit: too much code to write all by myself, whereas Visual Studio Wizards cover almost (almost) everything.

Using the Code

There is very little code itself, because VS generates almost everything automatically.

First of all, a report template is required (prepare/acquire one yourself).

I. Generate a Data Source using Visual Studio Interface, Which Includes:

  1. Data → Add New Data Source
  2. Database
  3. New Connection
  4. etc.

II. Take Whatever Wizards Created and Make a Custom Data Source Based on the Standard Code

Note: Changes affect automatically generated adapters classes (one for each table in my case).

I just copy-pasted the generated code removing hard coded values like connection string extraction from the application configuration file and replacing it with my custom method of obtaining database connections (variable is called _connection and I set it in InitConnection() to null).

You can also update SqlCommands objects in InitCommandCollection that are used to extract data from the database.

Note: Each adapter class for each table has its own connection and collection of commands.

Change Fill method to work with your custom connection and any parameters you wish to provide (stored procedure parameters in my case).

Note: At the end of Fill method there is an actual call, which is this.Adapter.Fill(dataTable). The thing is that InitCommandCollection is called internally and if you provide some, say, stored procedure parameters via Fill then store them in internal variables and supply during the initialization.

III. Usage

  1. Create your custom dataset like CustomDataSet ds = new CustomDataSet()
  2. Create as many adapters as required
  3. Call Fill method for each of the adapters with any parameters you want (provided method's interface has been amended)
  4. As the first parameter of the Fill method is a dataset object (or collection of objects), after all Fill methods complete, you will get a dataset filled with all requested data
  5. Supply your report object with the dataset generated

Points of Interest

It was quite amazing to spend so much time resolving such a relatively minor problem, because there is no explanation of what to do. 

History

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)