//
you're reading...
ActiveReports, Technology

Using LINQ in ActiveReports

David, the TiredBlogger, shows us how to use LINQ as a data source in ActiveReports for .NET.

Jon, one of our support techs, did notice that David was using the Fields collection outside of the FetchData/DataInitialize event. Breaking one of our three rules for report design with ActiveReports.  [Edit: I forgot to add this before hitting the publish button] I believe the correct way of doing this is to use bind the textbox to the field, then access the textbox’s Value property during the Format event.

Tip of the hat to Luc, for sending this to me.

Advertisements

About James

I am a Senior Developer/Consultant for InfoPlanIT, LLC. I previously spent over 7 years as a Product Manager for what eventually became ComponentOne, a division of GrapeCity. While there, I helped to create ActiveReports 7, GrapeCity ActiveAnalysis, and Data Dynamics Reports.

Discussion

9 thoughts on “Using LINQ in ActiveReports

  1. Quite true, though there are forum discussions on the DD Forums pondering that exact same question–while a “rule” exists, if you’re generating your datasource and fields at the same time, there won’t be any transformations or unintended consequences to worry about. It also saves processing to remove an uneeded event handler.

    To that point, to “comply”, the Fields.Add methods can be readded to the DataInitialize event without any change to the functionality of the code.

    Also, by “bind the textbox to the field”, could you elaborate? It was my understanding that this occured by editing the properties of the data object (textbox, richtextbox, label, etc) and setting the DataField to the column/property name of your datasource. But, that setting that was arbitary and still required forcefeeding it using the _Format section. Is that not the case?

    Posted by David | July 17, 2007, 7:49 am
  2. David,

    Basically, the DataInitialize and FetchData events are used when designing unbound reports. All fields should be added to the report during the DataInitialize event, then the fields should be populated with data during the FetchData event.

    Since your sample is bound to an object that implements IList, ActiveReports for .NET automatically adds the fields and populates them with data behind the scenes. Fields are added to the report based on the names of the type’s properties, therefore you do not have to explicitly use Fields.Add(). All you really have to do is bind TextBoxes to the fields created by the reporting engine. To do this use the TextBox’s DataField property, which can be set at design time or in the ReportStart event at runtime.

    For instance, in the sample provided on your blog, you could use the following code in the ReportStart event to bind the TextBoxes to fields:

    Type.DataField = “ExceptionTypeName”;
    Count.DataField = “Count”;
    Percent.DataField = “Percent”;
    Percent.OutputFormat = “0.00%”;

    For simple reports, you may not run into any issues, however, in more complicated reports (for instance with grouping, subreports, etc), the FetchData event may fire multiple times before the next Section Format event is fired. In some cases the FetchData and Section Format events may appear to be synchronized, when, in fact, they are not.

    -Jon

    Posted by Jon | July 17, 2007, 1:10 pm
  3. Okay, that makes sense; I’ve never seen it explained like that before. Cool. Though, that leads me to another question: where would you handle your BLL code for data transforms and such. Say, for example, your database is returning a code and you want to turn it into printable text. In the past, I’ve done something along the lines of:

    in detail_Format
    Names.Html = ConvertIdToNames(Fields[“Ids”].Value.ToString());

    But, you’re saying I should do something like:

    in Data_Initialize
    Fields.Add(“Names”);

    in FetchData
    Fields[“Names”].Value = ConvertIdToNames(Fields[“Ids”].Value.ToString());

    Though you’re still going to need to place a call somewhere, whether it be in details_Format or not, to the field to populate richTextBox controls. Simply allowing it to preslug from the fields puts it into Text, not Html.

    richTextBox1.Html = Fields[“Names”].Value.ToString();

    Would the alternative be to create an internal string variable and use that instead of populating fields? Such as:

    In the reportbody:

    internal string names;

    In FetchData

    names = ConvertIdToNames(Fields[“Ids”].Value.ToString());

    In detail_Format

    richTextBox1.html = names;

    I understand, I think, what you’re staying, but I’m just not sure how to apply “the rules” to situations where a great deal of data manipulation is being handled by the report–not simply dropping a data object onto it.

    Thanks!

    -dl

    Posted by David | July 17, 2007, 2:35 pm
  4. Hi David,

    Our walk through on using RichText and Field merging does just what you suggest as an alternative; assign the value to a string then place that string in the rich text box during the Format event.

    Posted by James | July 17, 2007, 3:35 pm
  5. Yeah, I spent a bit of time rehunting through the forums and docs and I came across that. Very interesting…

    It mentions populating the reference variables during FetchData; however, as Jon pointed out, “the FetchData event may fire multiple times before the next Section Format event is fired.” Wouldn’t that waste resources because you’re refilling the same variables with the same values? Is there a way to control “may fire”–especially for single-pass fields located in page_header and such? What defines “may fire”?

    Posted by David | July 17, 2007, 7:44 pm
  6. David,

    Yes, you are absolutely correct in that assumption that any conversions to the data should be handled in the FetchData event before it is assigned to the field that will be bound to report controls. I always recommend, however, that business logic be handled outside of the report object. Even though this is not necessary, it makes for a more object oriented approach.

    I suggest handling the data access in data objects, business logic in the business objects, and finally, presentation on the report object.

    Even though with LINQ you are pulling data directly from a data source, you could always add another layer between the data returned by LINQ and the report that handles the business logic. As long as you end up passing in an object to the report’s DataSource property that the ActiveReports engine supports as a data source (for instance an object that implements IList) everything should work.

    -Jon

    Posted by Jon | July 17, 2007, 8:25 pm
  7. Ahh, good point; most of my old reports do pass a DataTable (or something similar) at report creation to the DataSource property. This may be a point to note that a lot of this is oversimplification by example. LINQ just adds another layer there that should be encapsulated, and, in most cases, would be thus rendering it non-point.

    Thanks to you both for the information–while I realized the “rules” where there, I’ve never found as good of an explaination as Jon provided on why. Perhaps a suggestion–your walkthrough (for the rules) says: “There is never a need to access the Fields collection outside of the FetchData or DataInitialize event” on number one. Perhaps using what we’ve discussed here… provide an example of where you SHOULD be putting this information.

    Thanks again!

    -dl

    Posted by David | July 17, 2007, 9:24 pm
  8. Just to let interested parties know, I am planning on posting my own sample regarding ActiveReports for .NET and LINQ on my blog.

    Should be ready tomorrow…

    Posted by Jon | July 18, 2007, 10:14 pm

Trackbacks/Pingbacks

  1. Pingback: Excellent Conversation regarding ActiveReports « Ramblings of the Sleepy… - July 17, 2007

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Archive

%d bloggers like this: