# Integration with FlexReport

## Content

The data aggregation functionality of [ComponentOne DataEngine](/componentone/docs/services/online-dataengine/overview)  is faster than any other column-oriented storage approach and processes millions of records in less than a second. You can utilize the potential in integration with other components, especially with **ComponentOne FlexReport**. When working with  **C1FlexReport** and large datasets, there can be a need to retrieve specific data based on certain groupings. For example, if you are working on some sales data, you might need to create a report to show the number of sales per country, or you might need to create a report to display the data based on the unique combinations of region and country.
In case you need to render about one million records in the report, the **C1DataEngine** in integration with **C1FlexReport** will give you the opportunity to process the data and generate the report in fraction of a second.
To understand more on the functionality, the following steps provide guidance on how you can create a report to display the sales data per country using **C1DataEngine**.
To accomplish this, you need to:

1. **Design a Flat Report**
2. **Get the Required Data**
3. **Render the Report in FlexViewer**

### 1\. Design a Flat Report

Initially you need to design a flat report based on the requirements. In this sample the flat report, displays sales data by country. First, add **TextFields** to the detail section for your database values, then design the layout that suits your needs. We have formatted the report in such a way that each record group will be shown in the form of a card, as presented in the following screenshot:
![C1DataServices DataEngine - Report designer showing a sales report card layout.](https://cdn.mescius.io/document-site-files/images/09dc0709-b6e6-44f2-a87a-75d899f9cf2c/images/flatreportdesign.png)

After this, create a Windows Forms Application, add the FlexReport component to load your report, and FlexViewer control into your form to render the report.

![C1DataServices DataEngine - Windows Forms application displaying a FlexViewer control with report viewing and printing toolbar.](https://cdn.mescius.io/document-site-files/images/09dc0709-b6e6-44f2-a87a-75d899f9cf2c/images/design.png)
To load the report via code, use the following:

```csharp
c1FlexReport1.Load(@"..\..\SalesReport.flxr", "SalesReport");
```

### 2\. Get the Required Data

To obtain the aggregated data from the referenced dataset the **C1DataEngine** API will be used as the data source of the FlexReport.
To get the required data, you first need to add the following required packages for using the C1DataEngine API:

* **C1.DataCollection.BindingList**
* **C1.DataEngine**
* **C1.DataEngine.Collection**

This sample will handle one million records via a CSV file containing the sales data. First, initialize the [Workspace](/componentone/docs/services/online-dataengine/quickstart) and [IDataCollection](/componentone/api/services/online-dataengine/dotnet-standard-api/C1.DataEngine.Collection/C1.DataEngine.C1DataEngineCollection.html) objects and create a class containing properties that can hold the data corresponding to the fields in the CSV file.

```auto
private Workspace _workspace;
private IDataCollection<object> _dataCollection;
class SalesData
{
    public string Region { get; set; }
    public string Country { get; set; }
    public string ItemType { get; set; }
    public string SalesChannel { get; set; }
    public string OrderPriority { get; set; }
    public DateTime OrderDate { get; set; }
    public string OrderID { get; set; }
    public DateTime ShipDate { get; set; }
    public int UnitsSold { get; set; }
    public double UnitPrice { get; set; }
    public double UnitCost { get; set; }
    public double TotalRevenue { get; set; }
    public double TotalCost { get; set; }
    public double TotalProfit { get; set; }
}
```

To get the complete one million records in your **Workspace** object use the [CsvReader](/componentone/docs/services/online-dataengine/workwithdataengine/connectdataengine/importdatafromcsv) as given in the code snippet below:

```csharp
//Initialize a new workspace folder relative to the project root directory
workspace = new Workspace();
workspace.Init("workspace");
//Read CSV data and convert it into a collection of custom .NET objects
var reader = new StreamReader(@"..\..\Sales Records.csv");
var csv = new CsvReader(reader, CultureInfo.InvariantCulture);
var salesDataList = csv.GetRecords<SalesData>().AsEnumerable();
//Import CSV data from custom collection to a DataEngine table
ObjectConnector<SalesData> connector = new ObjectConnector<SalesData>(workspace, salesDataList);
connector.GetData("SalesData");
workspace.Save();
```

The specific data that will be extracted from the database is the **TotalCost, TotalRevenue,** and **TotalProfit**
for each unique country, and this can be done via **query** using the **Op** class of the **C1.DataEngine** assembly.
The results of DataEngine queries are cached, making subsequent executions even more quickly. This query remains cached until the underlying data is refreshed. You can refresh data periodically, for example, hourly or daily, by checking a saved time stamp.

```csharp
dynamic salesTable = workspace.table("SalesData");
dynamic query = workspace.query("SalesByCountry", new
{
Country = salesTable.Country,
TotalCost = Op.Sum(salesTable.TotalCost),
TotalProfit = Op.Sum(salesTable.TotalProfit),
TotalRevenue = Op.Sum(salesTable.TotalRevenue),
});
```

Use the [C1DataEngineCollection](/componentone/api/services/online-dataengine/dotnet-standard-api/C1.DataEngine.Collection/C1.DataEngine.C1DataEngineCollection.html) class to get the data from the workspace based on your specific query and **C1DataCollectionBindingList** class to be assigned as the data source of your FlexReport based on your **C1DataEngineCollection** object.

```csharp
C1DataEngineCollection _dataCollection = new C1DataEngineCollection(workspace, query);
c1FlexReport1.DataSource.Recordset = new C1DataCollectionBindingList(_dataCollection);
```

### 3\. Render the Report in FlexViewer

For the report to appear in the FlexViewer at runtime, you must bind the FlexReport to the FlexReport's **DocumentSource** property.

```auto
c1FlexViewer1.DocumentSource = c1FlexReport1;
```

The report will get rendered in a short amount of time after following all the above processes, and look as in the GIF below:
![C1DataServices DataEngine - Animated FlexGrid demo showing data sorting, filtering, editing, and navigation within a grid.](https://cdn.mescius.io/document-site-files/images/09dc0709-b6e6-44f2-a87a-75d899f9cf2c/images/flexgriddemo.gif)
This demo can be downloaded [here.](https://global-cdn.grapecity.com/blogs/componentone/20220725-build-500000-row-report-in-seconds-using-net-data-engine/LargeDatasetDemo.zip)