Rob Allen
Rob Allen

Reputation: 17719

Bind an ObjectDataSource to an existing method in my Data access layer

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

Answers (6)

Siniša Bencetić
Siniša Bencetić

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

Rob Allen
Rob Allen

Reputation: 17719

In order to use a standard .Net DataSet as an DataSource for a Reporting Services Report I had to:

  1. Create an ADO DataSet which uses the same stored procedure as the DAL method

  2. Use the ADO DataSet to populate the fields in the Report in the designer

  3. 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()
    
  4. 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

chriscena
chriscena

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

Robert C. Barth
Robert C. Barth

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

Perpetualcoder
Perpetualcoder

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

mtt
mtt

Reputation: 113

do you use object data source or datatable? make a choose from one of them that not to be duplicate

Upvotes: 0

Related Questions