What is the most elegant way to pass RDL file, SQL and Connection string to ReportViewer Control on Winform C# project for displaying report at run time.
Introduction:
- I recently started working on Report creation on Windows. I found that RDLC files act as static files with no need for Connection string or SQL statements, so we need to pass DataSource to it in order to fill it with data at run time. This does not serve our purpose.
- RDL files however can take SQL statements and Connection String which they save in XML tags and are used for generating Dynamic reports.
Given that I have
- RDL report template
- SQL statement
- Connection String to Database
What is the best way to pass this information to a ReportViewer in C# Winform, to generate report?
1) For an RDL used for a library management system. (we have no control over these files, these are used by the users of our application).
<Query>
<DataSourceName>DS1</DataSourceName>
<CommandText>select bk_book_details.id, bk_book_details.book_id, bk_book_details.book_no, bk_book_details.book_name, bk_book_details.edition_id, bk_book_details.condition_id, bk_book_details.publication_year, bk_book_details.price, bk_book_details.purchase_price, bk_book_details.reference_no, bk_book_details.book_status, bk_book_details.purchase_id, bk_book_details.purchase_date from bk_book_details</CommandText>
</Query>
2) Here is the SQL statement
select bk_book_details.id, bk_book_details.book_id, bk_book_details.book_no, bk_book_details.book_name, bk_book_details.edition_id, bk_book_details.condition_id, bk_book_details.publication_year, bk_book_details.price, bk_book_details.purchase_price, bk_book_details.reference_no, bk_book_details.book_status, bk_book_details.purchase_id, bk_book_details.purchase_date from bk_book_details
3) Here is the Connection string
server=localhost;User Id=root;password=root;Persist Security Info=True;database=lms
Current output: As seen on the RDLReader.exe application
Code used to get this output
private void btnReport_Click(object sender, EventArgs e) {
string sql = "select bk_book_details.id, bk_book_details.book_id, bk_book_details.book_no, bk_book_details.book_name, bk_book_details.edition_id, bk_book_details.condition_id, bk_book_details.publication_year, bk_book_details.price, bk_book_details.purchase_price, bk_book_details.reference_no, bk_book_details.book_status, bk_book_details.purchase_id, bk_book_details.purchase_date from bk_book_details";
string RDLReaderApplication = @"""""""" + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @""\ReaderPath\RDLReader.exe"" + @"""""""";
string reportFile = @"""""""" + Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + @""\Reports\ReportFile.RDL"" + @"""""""";
string connectionString = @"""""""" + "server=localhost;User Id=root;password=root;Persist Security Info=True;database=lms" + @"""""""";
Process.Start(RDLReaderApplication, reportFile + "" "" + @"""""""" + sql + @"""""""" + "" "" + connectionString);
}
Expected output:
Work so far:
The form ReportForm
contains the ReportViewer
Control which is docked to the form.
Additional information:
1) I want the 3 data to be sent to ReportViewer
Control, that is docked in a different form and load the report on the ReportViewer instead.
2) Our users do not share connection with us, so we cannot hardcode it in the RDL file. The SQL is generally a constant and RDL file is generally designed once per need for a particular form.
3) We use MySQL database for now. But a solution in any popular RDBMS will help a lot. I hope the query above gives a good picture of the schema of the table being accessed (the query contains all the columns in the table).
Note: Please include answer with RDL files and not RDLC files.
What finally solved the problem for me, in addition to the answer given by @Reza Aghaei
The Report file has tags for datasource and dataset, right at the beginning of the RDL file like the following snippet
<DataSets>
<DataSet Name="Data">
<Query>
<DataSourceName>DS1</DataSourceName>
The line from @Reza Aghaei, asking for the name of DataSet (Data) and not DataSourceName (DS1). Making this distinction was crucial in making the report file work.
var rds = new Microsoft.Reporting.WinForms.ReportDataSource("DataSet1", this.ReportData);
changed this to:
var rds = new Microsoft.Reporting.WinForms.ReportDataSource("Data", this.ReportData);