Reputation: 17719
I've seen the designer code, and I have seen code which builds the ObjectDataSource in the code-behind, however both methods communicate directly with the database via either text commands or stored procs. This seems like unnecessary code duplication to me since my data access layer has a method already which returns a datatable with the data I need for this report.
How can I programmatically build and link the ODS to my data access layer's method?
EDIT:
Thanks to everyone who answered. This was very poorly phrased on my part. There was too much that I did not understand when I wrote this question originally. What I should have asked is:
How do I programmatically bind a .Net Reporting Services Report (*.rdlc) to a method in my Data Access Layer instead of an ADO.Net DataSet.
See my answer below.
Upvotes: 2
Views: 8523
Reputation: 31
Here's my solution. I have traditional project with data layer named "Data". Now my RDLC's are hosted in main web project "Web". So there is my .NET type in "Data":
Data.Models.Reports.MyRepository
; and method in that type:
GetMyReport
Luckily ReportDataSource has overload method Add which accepts IDataSource as second parameter. Once you got that everything is clear.
//Create object data source
ObjectDataSource objDataSource = new ObjectDataSource();
objDataSource.TypeName = "Data.Models.Reports.MyRepository";
objDataSource.SelectMethod = "GetMyReport";
//Add parameters if any ...
objDataSource.SelectParameters.Add("Param1", "");
Here is the magic. Object data source is perfectly acceptable as second param in constructor
ReportDataSource rptDataSource = new ReportDataSource("DataSet1",objDataSource);
reportViewer.LocalReport.DataSources.Add(rptDataSource);
Works like a charm for me.
Upvotes: 1
Reputation: 17719
In order to use a standard .Net DataSet as an DataSource for a Reporting Services Report I had to:
Create an ADO DataSet which uses the same stored procedure as the DAL method
Use the ADO DataSet to populate the fields in the Report in the designer
In the aspx page, use the following:
<rsweb:ReportViewer ID="ReportViewer1" runat="server" Font-Names="Verdana"
Font-Size="8pt" Height="655px" Width="980px">
<ServerReport ReportServerUrl="" />
<LocalReport>
</LocalReport>
</rsweb:ReportViewer>
And in the code-behind:
ReportViewer1.ProcessingMode = ProcessingMode.Local
Dim report As LocalReport = ReportViewer1.LocalReport
report.ReportPath = "<your report path>"
report.DataSources.Clear()
Dim rds As New ReportDataSource()
rds.Name = "<dataset name>_<stored proc name>"
rds.Value = <your DAL method ()>
report.DataSources.Add(rds)
report.Refresh()
Once you have tested this and are comfortable with the report you get, you can safely exclude the ADO DataSet from your project.
Notes: This is far from ideal and there are likely steps I did which are unnecessary or something I missed.
One thing that gave me a real headache was that the XML in the RDLC contained definitions for old ADO datasets that were no longer relevant. To strip those out, right click the rdlc file in your Solution Explorer and select "Open With" then XML Editor in the next menu.
Upvotes: 2
Reputation: 478
When you say that the datasource communicates directly with the database, do you mean the SqlDataSource?
If you have a data access layer class it's rather easy to connect it to the ObjectDataSource. Just do it declaratively:
<asp:ObjectDataSource ID="ObjectDataSource1" runat="server"
SelectMethod="[InsertYourMethodHere]" TypeName="[InsertYourDALClassHere]">
<SelectParameters>
[Add Your Parameters Here]
</SelectParameters>
</asp:ObjectDataSource>
If you use the designer it can be smart to decorate your DAL class with the DataObject and DataObjectMethod attributes. If you'd rather do it programmatically, just use the same properties in your codebehind.
Upvotes: 0
Reputation: 23315
The question doesn't make a whole lot of sense. If there's an ObjectDataSource (ODS), then that is probably being used to fill whatever control is displaying the data (mostlikely via the DataSourceID field). On the markup page, you'll see the ODS has the name of the class and the name of the method on that class to retrieve the data. That doesn't mean it's doing it twice, that's just how you set it up.
Upvotes: 0
Reputation: 13571
An object datasource can bind to any object who's class implements IEnumerable. If your DAL method is returning collections or DataTable/DataView or things on the same line. You just need to assign the object datasource object's datasource property with the return val of the method and call DataBind(). You may even use the Data Server Control's DataSource property directly and do the same.
Upvotes: 0
Reputation: 113
do you use object data source or datatable? make a choose from one of them that not to be duplicate
Upvotes: 0