using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace SSRSMockup { public class TestReportInfo { public TestReportInfo(string cEmpName, decimal nSalary, string cNotes) { this.EmpName = cEmpName; this.Salary = nSalary; this.Notes = cNotes; } private string _EmpName; public string EmpName { get { return _EmpName; } set { _EmpName = value; } } private decimal _Salary; public decimal Salary { get { return _Salary; } set { _Salary = value; } } private string _Notes; public string Notes { get { return _Notes; } set { _Notes = value; } } } }I can populate it in code like so and push it to the report as a 2nd datasource:
//Create a 1st dataSource for the report //Create a list List<TestReportInfo> oList = new List<TestReportInfo>(); //Populate the list based on the class TestReportInfo oList.Add(new TestReportInfo("John Smith", 90000,"Notes")); oList.Add(new TestReportInfo("Stacy Keach", 95000,"Notes")); oList.Add(new TestReportInfo("Michael Ranes", 99000,"Notes")); //Create a datatable from the list olist DataTable odt = new DataTable(); //ListToDataTable function Added below odt = ListToDataTable(oList); //this is just a function that puts the list into a datatable to push it to a report as a demo ReportDataSource odtReportData = new ReportDataSource("SSRSMockup_TestReportInfo", odt); reportViewer.LocalReport.DataSources.Add(odtReportData);I can then add another datasource created on the fly (as long as a datasource with the same name and structure was used in the designing of the report - you can use multiple datasources in a report):
// Add the Employee data source as a 2nd datasource reportViewer.LocalReport.DataSources.Add(GetEmployees(dialog.Parameters[0])); // This example just goes through different layers to generate a list of employees from an entity class - generate the list anyway you want private ReportDataSource GetEmployees(Microsoft.Reporting.WinForms.ReportParameter customers) { string criteria = null; MyCompany.Persistence.Factories.Common.EmployeeFactory oFactory = new MyCompany.Persistence.Factories.Common.EmployeeFactory(); List<EmployeeEntity> oList = new List<EmployeeEntity>(); IDataReader rdr = null; MyCompany.DataAccess.SQLProcedure oSQLProcedure = new SQLProcedure(SQLProcedure.DB.Data); string lcSQLString = "select cast(empl_id as varchar(15)) as idkey, * from employee where elname like 'G%' order by elname, efname"; if (lcSQLString.Length > 0) { oSQLProcedure.SelectRecord(lcSQLString, ref rdr); Dictionary<string, bool> dcFields = oSQLProcedure.GetExistFields(rdr); while (rdr.Read()) { oList.Add(oFactory.CreateEntity(rdr, dcFields)); // this is just stuff from different layers that creates an entity object } } //The name of the datasource MUST match the name configured at design time see designer.cs // from designer.cs: reportDataSource1.Name = "MyCompany_Entities_Common_EmployeeEntity"; // from designer.cs: reportDataSource1.Value = this.employeeEntityBindingSource; return new ReportDataSource("MyCompany_Entities_Common_EmployeeEntity", oList); }and now I would have 2 datasources for the report. You must push all of the datasources used in the designing of the report. If your report requires 3 datasources, then 3 datasources should be added in code and they must match the name and structure of those used in the designing of the report. Hope that helps.