New to Telerik Reporting? Download free 30-day trial

Binding ObjectDataSource Component to a BusinessObject

The following code sample illustrates a custom middle-tier business object that can be used with an ObjectDataSource component that specifies a strongly typed source object. The example demonstrates also how to configure the report to use the ObjectDataSource and how to preview it in the Windows Forms Report Viewer with code.

The ObjectDataSource component may be configured in the Telerik Report Designers without the need for writing additional code. It may be necessary to extend the Reporting engine to recognize the custom assembly with the data providing logic through the assemblyReferences Element in the Telerik.Reporting section of the designer's configuration file.

Remarks

The business object exposes several methods which return different data types. They represent only part of the data types which are supported by Telerik Reporting and can be used to feed an item with data. Additionally, methods with arguments are implemented which can be also invoked from the ObjectDataSource component. When the data method contains parameters the Parameters collection of the ObjectDataSource should be used to pass values to them at runtime. To successfully invoke the data method, the parameters number, their names and types should match. The order of the parameters in the Parameters collection is not important. If there is a discrepancy between ObjectDataSource parameters and the method parameters you will receive a runtime exception that the method cannot be resolved.

The business object is marked with the DataObjectAttribute which indicates that the object is suitable for data binding. Objects marked with this attribute will be shown in the ObjectDataSource wizard when "Show only data components" checkbox is checked. Respectively the methods used for data retrieval are marked with the DataObjectMethod attribute.

Example

class Product
{
    public string Name { get; set; }
    public string ProductNumber { get; set; }
    public decimal ListPrice { get; set; }
    public int ProductModelID { get; set; }
    public string Color { get; set; }
}

[DataObject]
class Products
{
    const string SelectCommandText =
            "SELECT Name, ProductNumber, ListPrice, ProductModelID, Color" +
            "  FROM Production.Product" +
            "  WHERE ProductModelID is not NULL" +
            "    AND Color is not NULL";

    const string ConnectionString =
            "Data Source=(local)\\SQLEXPRESS;Initial Catalog=AdventureWorks;Integrated Security=True";

    [DataObjectMethod(DataObjectMethodType.Select)]
    public DataTable GetDataTableSource()
    {
        DataTable dataTable = new DataTable();
        SqlDataAdapter dataAdapter;
        using (dataAdapter = new SqlDataAdapter(SelectCommandText, ConnectionString))
        {
            dataAdapter.Fill(dataTable);
        }
        return dataTable;
    }

    [DataObjectMethod(DataObjectMethodType.Select)]
    public IDataAdapter GetDataAdapterSource()
    {
        return new SqlDataAdapter(SelectCommandText, ConnectionString);
    }

    [DataObjectMethod(DataObjectMethodType.Select)]
    public DataView GetDataViewSource(string name)
    {
        SqlDataAdapter dataAdapter = new SqlDataAdapter(SelectCommandText, ConnectionString);
        DataTable dataTable = new DataTable();

        dataAdapter.Fill(dataTable);

        DataView dataView = dataTable.DefaultView;
        dataView.RowFilter = string.Format("Name like '%{0}%'", name);

        return dataView;
    }

    [DataObjectMethod(DataObjectMethodType.Select)]
    public Product[] GetArraySource()
    {
        return this.GetAllProducts().ToArray();
    }

    [DataObjectMethod(DataObjectMethodType.Select)]
    public ArrayList GetArrayListSource()
    {
        ArrayList arrayList = new ArrayList();
        foreach (var product in this.GetAllProducts())
        {
            arrayList.Add(product);
        }
        return arrayList;
    }

    [DataObjectMethod(DataObjectMethodType.Select)]
    public List<Product> GetAllProducts()
    {
        SqlConnection connection = new SqlConnection(ConnectionString);
        SqlCommand command = new SqlCommand(SelectCommandText, connection);
        SqlDataReader reader = null;
        List<Product> products = new List<Product>();

        try
        {
            connection.Open();

            reader = command.ExecuteReader();

            while (reader.Read())
            {
                products.Add(new Product()
                {
                    Name = reader.GetString(0),
                    ProductNumber = reader.GetString(1),
                    ListPrice = reader.GetDecimal(2),
                    ProductModelID = reader.GetInt32(3),
                    Color = reader.GetString(4)
                });
            }
        }
        catch
        {
            // Handle exception.
        }
        finally
        {
            if (reader != null)
            {
                reader.Close();
            }
            connection.Close();
        }
        return products;
    }

    // Gets products bellow a specified max price.
    [DataObjectMethod(DataObjectMethodType.Select)]
    public IList<Product> GetProducts(decimal maxPrice)
    {
        return this.GetAllProducts().FindAll(product => product.ListPrice <= maxPrice);
    }

    // Gets products of specific model and a color.
    [DataObjectMethod(DataObjectMethodType.Select)]
    public IList<Product> GetProducts(int productModelID, string color)
    {
        return this.GetAllProducts().FindAll(product => (product.ProductModelID == productModelID && product.Color == color));
    }
}

void Form1_Load(object sender, EventArgs e)
{
    // Creating and configuring the ObjectDataSource component:
    var objectDataSource = new Telerik.Reporting.ObjectDataSource();
    objectDataSource.DataSource = typeof(Products); // Specifying the business object type
    objectDataSource.DataMember = "GetProducts"; // Specifying the name of the data object method
    objectDataSource.CalculatedFields.Add(new Telerik.Reporting.CalculatedField("FullName", typeof(string), "=Fields.Name + ' ' + Fields.ProductNumber")); // Adding a sample calculated field.

    // Specify the parameters, their types and values
    objectDataSource.Parameters.Add(new Telerik.Reporting.ObjectDataSourceParameter("color", typeof(string), "Silver"));
    objectDataSource.Parameters.Add(new Telerik.Reporting.ObjectDataSourceParameter("productModelID", typeof(int), 23));

    // Creating a new report
    var report = new Report1();

    // Assigning the ObjectDataSource component to the DataSource property of the report.
    report.DataSource = objectDataSource;

    // Use the InstanceReportSource to pass the report to the viewer for displaying
    var reportSource = new Telerik.Reporting.InstanceReportSource();
    reportSource.ReportDocument = report;

    // Assigning the report to the report viewer.
    reportViewer1.ReportSource = reportSource;

    // Calling the RefreshReport method in case this is a WinForms application.
    reportViewer1.RefreshReport();
}

To use this code in the Report Designer Tools, the data retrival methods must be built in separate assembly and specifically configured before it can be resolved by the Report Designers - Connecting the ObjectDataSource component to a Data Source