tags:

views:

727

answers:

2

Hello,

I am using rdlc reports to report off some businesss objects. I use subreports to report off of nested objects (as described here).

When using a regular list of child objects, like IList(Of Books), I create a datasource for books, and then use this as the datasource of the subreport.

I'm little stuck how to use this technique when the nested object is an IList(Of String), or another list of a primitive type.

What's the best way to do the reporting in this scenario?

A: 

I encountered a similar problem. I had a report running of a list of CustomObject. The CustomObject list was populated from a query on a list of ParentObjects that contained many-many references to all their CustomObjects. The relationship was removed and a string column was used on the ParentObject (ParentObject.CustomObjectName) instead. Now my report receives a string[] containing all the CustomObject names.

My solution was creating a wrapper object with a single string property and a constructor to use as my data source. I named it just like the CustomObject my report was expecting.

class CustomObject 
{ 
   public string Name {get; set;} 

   public CustomObject(string name)
   {
      Name = name;
   }
}

I load my list using LINQ, I call the wrapper constructor in the select statement

var wrappedObjects = from parent in GetParentObjects()
   select new CustomObject(parent.CustomObjectName);

From the report you can add a data source for the CustomObject class like you normally would and access the object as usual "=Fields!Name.Value".

Luis
A: 

I have an object structure like so

Order -> List:OrderItems(Products) -> List:AdditionalProducts(Products)

I have a main report with a subreport and a subsubreport.

I fixed this in the following way

In the subreport I pass a parameter to the subsub report. this parameter has a value of the product name and is called "thisproduct".

The subreportprocessing function is called by both the subreport and the subsub report. So I need to assign the data source for the both in here.

  1. I assign the data source for the subreport (order.items)

  2. I add a "if" for if the subsubreport (InternalOrderItemAdditionalProducts) is calling this function. in here i check the parameter, and get the product name. I can then loop through the orderitems, find the one relating to the product being looked at, and then assign the subsubreport datasource to be the additionalproducts related to that product.

     private void SubreportProcessing(object sender, SubreportProcessingEventArgs e)
      {     
      // assign subreport datasource
      e.DataSources.Add(new ReportDataSource("OrderItems", order.Items));
    
    
      // if the subsubreport is calling this then
      if (e.ReportPath != null)
          if (e.ReportPath == "InternalOrderItemAdditionalProducts")
          {
              // find the orderitem relating to this product
              foreach (var orderitem in order.Items)
              {
                  if (e.Parameters["thisproduct"].Values[0] == orderitem.ProductType.Name)
                  {
                      // assign the subsubreport datasource to be the additional products of that order item
                      e.DataSources.Add(new ReportDataSource("AdditionalProducts",
                                                             orderitem.Product.AllDescendentAdditionalProducts));
                  }
              }
          }
    

    }

Karen Hurley