In my previous post I stated that I had succeeded in converting a Reporting Services Data Processing Extension for reporting on ad-hoc data from a serialized ADO.Net DataSet into VB.Net. I have since extended this with an extra parameter (IDataParameterCollection) to allow the report designer to define at design-time (or indeed at run-time) which DataTable within the DataSet should be used as the source table. The implementation of DataProcessing.IDataReader also now iterates over a DataView of the table rather than the DataTable itself thus allowing me to pass a third parameter (actually passed via the Generic Query Designer as the command text (IDbCommand.CommandText)) which I then use as the RowFilter for the DataView.
This all works great. I can supply the parameters which I have told the extension to request from the designer (via the implementation of IDbCommandAnalysis.GetParameters method), and the query designer screen returns the data into the results screen, but if I attempt to navigate to the report layout tab, or I click on the 'Refresh Fields' button within the Generic Query Designer, I get an exception.
I deliberately decided to Debug.Assert that the @DataSource parameter should not be empty, but it should not be empty anyway as I have already supplied it via the designer. Following my debug trace information I can see that ExecuteReader in being called, but that the parameters are being passed as empty strings. If I elect to ignore the error then I can see via the trace that ExecuteReader gets called a second time, this time passing the parameters as I have entered them, and all is well.
The solution of course is not to require there to be non-empty parameters, but surely this is a bug?
UPDATE: after lots more detective work I have discovered that presumably the Report Designer graciously handles any ArgumentExceptions, and just carries on and attempts the ExecuteReader a second time.
How did I discover this? I turned off my assertions and just let the code proceed, the code gets as far as trying to load the DataSet:
Try dataset.ReadXml(dataSource)Catch ex As System.Exception Trace.WriteLine(String.Format("Error Reading XML into dataset: {0}:{1}", ex.Message, ex.GetType)) Throw exEnd Try
but inevitably it fails because the dataSource parameter is a blank string, so I catch an ArgumentException and write a message to the trace as follows:
Error Reading XML into dataset: The path is not of a legal form.:System.ArgumentException
The Report Designer then carries on and repeats the call to ExecuteReader, this time passing the correct parameters and everything goes smoothly.
So, still a bug in my opinion (unless anyone can enlighten me otherwise) - but it works!
UPDATE 2:
Robert Bruckner has now kindly enlightened me as follows (see also this thread):
If you actually execute the query when ExecuteReader(SchemaOnly) is calledthen the implementation is incorrect. For SchemaOnly execution, no parametervalues are passed in because no query should be executed - just the columnsshould be returned.When Refreshing Fields, the report designer first tries to determine thefields based on ExecuteReader(SchemaOnly) because this should not affect anydatabase state (and it is cheaper). If SchemaOnly fails, then reportdesigner tries to actually execute the query and determine the fields basedon the returned dataset. In order to execute the query it has to pass inparameter values.
Remember Me
a@href@title, strike
Disclaimer The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.