This is a migrated thread and some comments may be shown as answers.

Multiple collections in ObjectDataSource

6 Answers 267 Views
General Discussions
This is a migrated thread and some comments may be shown as answers.
Dmytro
Top achievements
Rank 1
Dmytro asked on 24 Sep 2019, 04:44 PM

We want to separate report layout from data generation logic. 

Our data generation logic is a class like this:

 

class Generator

{

     public Data Generate(/* parameters here*/);

}

 

Where Data is like this:

 

class Data

{

     public List<RowType1> List1;

     public List<RowType2> List2;

     // other collections

}

 

In order to feed this data to a report definition (created in Standalone Report Designer),the only option seems to be ObjectDataSource. However, it only supports one collection at a time. Thus, we need multiple  ObjectDataSource-s to expose all collections. This will result in multiple calls to Generator.Generate(), which looks really problematic.

 

Is there any way to do this elegantly with Telerik Reporting, while avoiding multiple calls to report generation logic and avoiding UI/logic mix?

6 Answers, 1 is accepted

Sort by
0
Neli
Telerik team
answered on 27 Sep 2019, 07:13 AM

Hello Dmytro,

Our ObjectDataSource component support Business objects - check Supported Object Types.

Basically, when you add the ObjectDataSource to the report and it points to the Generator class, you will see only one property - Generate (i.e. Fields.Generate). However, you still can display the data from the lists inside Generate. You will need to assign the DataSource of the List/Table/Crosstab item where the data of each list will be displayed through a Binding. For more information, refer to How to Databind to Collection Properties KB article. Note that you will not able to see the properties of the lists in Design time but they can be used, i.e. should be typed manually.

I hope the provided information will help. Let us know if you have further questions.

Regards,
Neli
Progress Telerik

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Dmytro
Top achievements
Rank 1
answered on 21 Nov 2019, 02:23 PM

Hi Neli,

thank you for reply. But i'm not sure if I completely get it.

So, i have this Generator class with Generate method (which potentially takes some parameters).

 

So, i've created an ObjectDataSource and set its "DataSource" method to "Generator" and "DataMember" to "Generate". I've also set "Parameters" to whatever parameters has to be passed. Is this correct so far?

 

Now, i add a Table component to my report and want to bind it's DataSource to List1 from the ObjectDataSource i have. How do I do that?

 

Best regards,

Dmytro

0
Neli
Telerik team
answered on 26 Nov 2019, 01:17 PM

Hello Dmytro,

From the description, it seems that so far everything is correct.

I prepared sample project which demonstrates the following approach:

1. Create a ClassLibrary which has to lists - one with cars and another with items;

2. Build the project;

3. Add a Report Library to the solution (in your case you will need to add the dll file to the Standalone Designer's location);

4. Add an assembly reference in a Telerik section to the App.config file of the report library:

<configuration>
  <configSections>
    <section name="Telerik.Reporting" type="Telerik.Reporting.Configuration.ReportingConfigurationSection, Telerik.Reporting" allowLocation="true" allowDefinition="Everywhere" />
  </configSections>
  <Telerik.Reporting>
    <assemblyReferences>
      <add name="ClassLibrary1"/>
    </assemblyReferences>
  </Telerik.Reporting>
</configuration>

5. Add an ObjectDataSource for the cars (select Cars() for the DataMember);

6. Add a table item -> select its datasource -> add the desired fields;

7. Repeat the same for the items.

You can check the attached project (Build first), as well as our DataBinding report which demonstrates how to assign a datasource to a list item. The report can be found at: C:\Program Files (x86)\Progress\Telerik Reporting <Version>\Examples\CSharp\ReportLibrary

 

Regards,
Neli
Progress Telerik

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Dmytro
Top achievements
Rank 1
answered on 27 Nov 2019, 10:04 AM

Hi Neli,

 

Thank you for your reply. While your sample project is useful, it does not actually answer my question.

You see, in your sample project you have 2 datasets, each of which creates a separate DataObject. Thus, in a scenario where business objects call a DB (or a REST service), this will result in 2 calls. That's exactly what i want to avoid as i've described in my initial posting:

 

> In order to feed this data to a report definition (created in Standalone Report Designer),

> the only option seems to be ObjectDataSource. However, it only supports one collection at a time.

> Thus, we need multiple  ObjectDataSource-s to expose all collections.

> This will result in multiple calls to Generator.Generate(), which looks really problematic.

 

Sorry, if this was not very clearly stated.

 

So ... is it possible to achieve what we need here while only having one DataObject created (and its Generate method called exactly once)?

 

Best regards,

Dmytro

0
Neli
Telerik team
answered on 02 Dec 2019, 09:29 AM

Hello Dmytro,

I made the following changes to the previously provided application:

In the ClassLibrary:

1. Remove the Cars and Items classes.

2. Create a new class named Data and add the following properties:

 

public class Data
{
    public List<Car> Cars { get; set; }
    public List<Item> Items { get; set; }
}

 

3. Create a class named Generator where we will add the data:

public class Generator
  {
      public List<Item> Items()
      {
          List<Item> items = new List<Item>();
          Item item;
          item = new Item("Reporting", 599);
          items.Add(item);

          item = new Item("DevCraft", 1499);
          items.Add(item);
          return items;
      }
      public List<Car> Cars()
      {
          List<Car> cars = new List<Car>();
          Car car;
          car = new Car("Honda", "NSX GT", 2003);
          cars.Add(car);

          car = new Car("Nissan", "Skyline R34 GT-R", 2005);
          cars.Add(car);

          car = new Car("Audi", "S4", 2006);
          cars.Add(car);
          return cars;
      }
      public Data Generate()
      {
          Data data = new Data() { Cars = this.Cars(), Items = this.Items() };
          return data;

      }
  }

3. Rebuild the solution.

 

Go to the ReportLibrary:

1. Remove the datasources;

2. Add a new ObjectDataSource and set is as follows:

- in Choose a Business Object dialog, select Generator;

- in Choose a Data Member -> Generate() : Data;

3. Set the ObjectDataSource to be the DataSource of the report;

4. Set the datasource of the tables through the following Bindings:

Property path: DataSource

Expression: =Fields.Cars / =Fields.Items

 

Regards,
Neli
Progress Telerik

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Feedback Portal and vote to affect the priority of the items
0
Dmytro
Top achievements
Rank 1
answered on 03 Dec 2019, 08:12 AM

Hi Neli,

 

thanks a lot, this is exactly what I was looking for!

 

Dmytro.

Tags
General Discussions
Asked by
Dmytro
Top achievements
Rank 1
Answers by
Neli
Telerik team
Dmytro
Top achievements
Rank 1
Share this question
or