Alex
Alex

Reputation: 35831

Define SSRS report's DataSet and DataSource dynamically

I'm building an MVVM Light WPF app using Visual Studio 2015 and Entity Framework 6. It needs to have some SSRS local reports running inside a Reports.xaml view (user control) using the WindowsFormsHost control:

<WindowsFormsHost x:Name="WindowsFormsHost">
    <rv:ReportViewer x:Name="ReportViewer" />
</WindowsFormsHost>

Following the instructions in this MSDN article, I've created a report with an embedded data source and dataset. However, now the app needs to have a ComboBox of report names to let the user choose which report to show in the ReportViewer control.

Here's what I'd like to do:

  1. Have a bunch of RDLC report files, each with the appropriate column names and layout information
  2. Be able to switch the dataset in code to call a different stored procedure via Entity Framework

I've tried manually removing the entire DataSources and DataSets tags from the RDLC file, but that blows it up and Visual Studio comes back with invalid XML errors.

Is it possible to have a report without the dataset/datasource embedded in the XML? Then the RDLC XML would provide the layout and the data would come from the code-behind?

Here's what I've tried in my Reports.xaml.cs code-behind from the MSDN article, but it uses embedded dataset and datasource:

public MainWindow()
{
    InitializeComponent();
    Messenger.Default.Register<string>(this, "RunReport", RunReport);
}

private void RunReport(string reportName)
{
    Microsoft.Reporting.WinForms.ReportDataSource reportDataSource1 = 
       new Microsoft.Reporting.WinForms.ReportDataSource();
    AdventureWorks2008R2DataSet dataset = new AdventureWorks2008R2DataSet();

    dataset.BeginInit();

    //Name of the report dataset in our .RDLC file
    reportDataSource1.Name = "DataSet1"; 
    reportDataSource1.Value = dataset.SalesOrderDetail;
    this._reportViewer.LocalReport.DataSources.Add(reportDataSource1);
    this._reportViewer.LocalReport.ReportEmbeddedResource = 
        "<VSProjectName>.Report1.rdlc";

    dataset.EndInit();

    //fill data into adventureWorksDataSet
    AdventureWorks2008R2DataSetTableAdapters.SalesOrderDetailTableAdapter salesOrderDetailTableAdapter = 
       new AdventureWorks2008R2DataSetTableAdapters.SalesOrderDetailTableAdapter();
    salesOrderDetailTableAdapter.ClearBeforeFill = true;
    salesOrderDetailTableAdapter.Fill(dataset.SalesOrderDetail);

    _reportViewer.RefreshReport();
}

Upvotes: 3

Views: 774

Answers (1)

R. Richards
R. Richards

Reputation: 25151

I think that a better approach to this would be to let the report decide what stored procedure to run based on the parameter value(s) that you pass. Let the report do what a report is meant to do, get and display data. The code behind handles what report to run and when.

The approach you describe smells like a good way to complicate the hell out reporting. Keep it simple, for your sake, and the sake of the person who has to manage the reports after you.

Upvotes: 1

Related Questions