Reporting Services 2005 with LLBL objects as the datasouce

Posts   
 
    
Ruizzie avatar
Ruizzie
User
Posts: 34
Joined: 14-Oct-2003
# Posted on: 23-Jun-2006 12:21:12   

Hiya,

In this thread there is some discussion about wether it would be possible to use LLBL objects as a datasource for Reporting Services 2005, local processing mode:

[url]/http://www.llblgen.com/tinyforum/Messages.aspx?ThreadID=5689)[/url]

After an afternoon and evening testing and 'working-around' I'd say, yes it is possible and it's pretty cool too imho sunglasses

Roughly speaking you can just follow the example Rajeev Karunakaran provides:

http://www.gotreportviewer.com/objectdatasources/index.html

This should point out how to use a LLBLGen datalayer as an object datasource. This works, but with the following caveats:

**- 1. Properties marked with the attribute Browsable(false) are unavailable in the report **

This means you can't reach related entities on 1:1 relations or master entities from 1:n relations. They are not available in the designer and can also not be reached by typing out the path in a textfield (eg. if you're in an Order, then Fields!Customer.Value.Name won't work).

**- 2. Automatic versioning of the datalayer wreaks havoc on report compatability **

The version info of the datalayer is saved in the report. Recompile your datalayer with automatic versioning and the next time you insert a field in the report it will add a new datasource to the report with the same name but a different version. This causes the report to not compile or execute. Very annoying.

Quick Solution to these issues

The solution that I came up with for the above problems is to create a new project with EntityRS classes that inherit from the normal Entity classes. Set the versionnumber for this project to a fixed value and problem nr. 2 is solved. You can recompile your datalayer all you want. Just make sure the datasource definition in the reports has all new fields in it. This does not always happen automatically.

To solve issue nr. 1 add properties to the new Entity classes overriding the existing Browsable(false) properties. You can then also use those in your report. Suddenly navigating entities as simple as in normal code.

Only problem now is that you can't cast from a normal Entity to a derived EntityRS class. So you have to construct them en copy the fields from the base Entity. The same goes for all related entities. This means the base entities are never passed to the report, just whole new entities with matching fields.

The EntityRS classes should look something like this:



public class OrderEntityRS : OrderEntity 
    {
        public OrderEntityRS(IEntityFields2 fields) : base(fields)
        { }

        public OrderEntityRS() : base()
        {
        }

    // Customer property
        public CustomerEntityRS CustomerRS
        {
            get
            {
                return new CustomerEntityRS(base.Customer.Fields);
            }
            set
            {
                this.Customer= new CustomerEntity(value.Fields);
            }
        
        }

    // Other properties..

    }


Ofcourse, creating new Entities based on the Fields array ignores custom attributes and does not set flags to match the source entity. But for the purpose of reporting is does suffice. Also you have to manually assign all related entities. So something of a Factory class to turn an Entity into a EntityRS is needed I think.

So, I think I am gonna spend some time and create a template which does all that.

The speed with which the reports are built makes it worth the effort for me. Also you have a tremendous amout of liberty to add custom properties etc. Plus there is the boon that you don't have to suddenly be developing queries as a datasource while the rest of your application is all based on ORM. And last but not least. The data does not have to be saved to the database before you can run a report. This makes previews etc. very easy.

If there are other idea's on how to streamline the above please let me know!

greetz, Ruizzie

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 24-Jun-2006 12:26:54   

Great post! simple_smile

Btw, I see you mention the ObjectDataSource, have you tried v2 beta with the LLBLGenProDataSource controls?

Frans Bouma | Lead developer LLBLGen Pro
Ruizzie avatar
Ruizzie
User
Posts: 34
Joined: 14-Oct-2003
# Posted on: 26-Jun-2006 10:10:38   

Frans, I did a quick test with Beta2. It seems to work about the same when it comes to Enities and datasets. The LLBLGenProDataSource is not functional in the Report Designer. It has a 'DefaultView' item which keeps coming back, but that is about it.

Perhaps it can be used at runtime but I don't really know what would be the advantage.

I also made some progress with a custom template set:

I now have a set of templates for creating derived 'RS' Entities. This works as described earlier. But....

In my initial tests I only used some 1:1 properties. I didn't try 1:m EntityCollection properties yet. I did that just yet, and there are some problems with these too:

  1. For one of the EntityCollections encountered in the (Entity) datasource a dataset is created à la:

<RootNamespace>_HelperClasses_EntityCollection, version 1.0. --automatic--

  1. For all other EntityCollections, no dataset is created, probably because the name of the other datasets would be the same as the first one.

  2. The EntityCollection dataset has to be filled separately from the original dataset with Entities. In the EntityCollection dataset the related entities from ALL entities in the first dataset have to be inserted. Kinda cumbersome disappointed

Solution?

Also create derived EntityCollections? That should solve the first two issues. I see no real solution for the third issue. Generating a utility function could help ofcourse.

So we're getting a bit farther away from cool and easy unfortunately.

But still, I'll keep on trotting. I got on this horse now.. and in the middle of a production project too simple_smile

I'll post the template set/config on my website if I happen to stumble on something that works.

Ruizzie avatar
Ruizzie
User
Posts: 34
Joined: 14-Oct-2003
# Posted on: 26-Jun-2006 12:35:46   

Doh! confused

As said before, for every 1:m EntityCollection property a new dataset is created in the report. And alas unlike some of it's competitors, RS 2005 does not support nested datasets.

So a simple Master-Detail report is only possible by using subreports!

That's a rather grave penalty to pay for using an object datasource.

Ofcourse... it's mentioned in the initial example.. but who really reads that?! disappointed

I guess you could use TypedLists and TypedViews to make joins between Master and Detail records. But what I liked the most about the idea was being able to access custom Entity properties.

Time for a healthy snack. Suggestions are welcome.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39927
Joined: 17-Aug-2003
# Posted on: 26-Jun-2006 23:11:54   

If you use 2 datasources? One for master and one for detail? (I am probably talking nonsense, but in asp.net 2.0 it works that way, you can't have master-detail with 1 datasource)

Frans Bouma | Lead developer LLBLGen Pro
Ruizzie avatar
Ruizzie
User
Posts: 34
Joined: 14-Oct-2003
# Posted on: 27-Jun-2006 10:06:51   

The point of the matter is that the layout of RS reports is the easiest to setup with Data Regions (list components).

A Data Region is based on one datasource (eg een collection of OrderEntities). Inside a Data Region you can nest other Data Regions, but these have to get their data from the same datasource. Unfortunately related EntityCollections are always in another datasource (Order.OrderLines is not reachable).

By inserting a subreport, another datasource can be used, but that demands handling an event to supply the subreport with the right datasource at runtime. This means your reports require undesirable amount of coding.

Regardless of the above, I am following this approach, with wrapper classes and all. Once you're into it, it's not so bad simple_smile

And who knows.. perhaps with the right RS extension it can get a bit more flexible yet.