Products

Solutions

Resources

Partners

Community

Blog

About

QA

Ideas Test

New Community Website

Ordinarily, you'd be at the right spot, but we've recently launched a brand new community website... For the community, by the community.

Yay... Take Me to the Community!

Welcome to the DNN Community Forums, your preferred source of online community support for all things related to DNN.
In order to participate you must be a registered DNNizen

HomeHomeUsing DNN Platf...Using DNN Platf...Administration ...Administration ...Pass dataset between modulesPass dataset between modules
Previous
 
Next
New Post
5/24/2007 12:02 PM
 

What is the best way to pass a dataset between two modules?  I thought about using IModuleCommunicator but that does not seem to be generic enough. I am trying to write a crystal reports module that will accept as input a dataset and a report name as input.

So when they press a button (or link etc.) the crystal report module will display, the crystal report will be loaded and use the dataset as its source.

thanks

Martin

 
New Post
5/24/2007 2:01 PM
 

is there a particular reason your reports module cannot simply obtain the datasource directly?

Depending on your dataset it would be quite cumbersome to try and share...


-Mitchel Sellers
Microsoft MVP, ASPInsider, DNN MVP
CEO/Director of Development - IowaComputerGurus Inc.
LinkedIn Profile

Visit mitchelsellers.com for my mostly DNN Blog and support forum.

Visit IowaComputerGurus.com for free DNN Modules, DNN Performance Tips, DNN Consulting Quotes, and DNN Technical Support Services
 
New Post
5/24/2007 3:43 PM
 

mitchel.sellers@gmail.com wrote

is there a particular reason your reports module cannot simply obtain the datasource directly?

Depending on your dataset it would be quite cumbersome to try and share...

I want to try and reeuse the reports module from other modules (with very different datasources). These other modules have datasets that the users filter to display on datagrids.  If I can just pass the dataset and the report name to the reports module and I would not have to go to the datasource (again) 

My (clumsy )solution was to create a global dataset that gets set by the calling module. The reports module then uses the global dataset to populate its dataset and loads the report (based on the Report Name parameter)

here is the code for the calling module:

 ======================================================
Private Sub cmdPrint_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles cmdPrint.Click

 

   GlobalVars.DataDS = Me.DataDS
   Dim sReportName As String = Server.MapPath(".") & "\DesktopModules\Modules\ReportName.rpt"

   Dim params As String
   params = "ReturnURLKey=ViewListKey"

   Response.Redirect(EditUrl("ReportName", sReportName, "IPReport", params), True)

End Sub
======================================================

from the Report module:
======================================================
Private Sub LoadCrystalReport()

 'Load the dataset from the global dataset
 Dim ds As New DataSet
 ds = GlobalVars.DataDS

 Me.Report = New ReportDocument

 Dim sReportName As String = Me.ReportName
 If FileExists(sReportName) Then
   'Load the report
   Me.Report.Load(sReportName)

   'Set the dataset
   Me.Report.SetDataSource(ds)

               
   crvShowReport.ReportSource = Me.Report
   crvShowReport.Visible = True

 End If

End Sub
======================================================

I am sure there is a better way to this thats why I thought I'd ask here.

thanks

Martin

 
New Post
5/25/2007 9:05 AM
 

I don't know what grid you are using, how crystal reports works, or your particular requirement so forgive me if my critique is way off; but this kind of solution could cause problems.  As I'm sure you know, when the page renders the dataset (for all practical purposes) is gone (stateless web).  So when the user is interacting with your grid, you are doing postbacks,  ajax calls (depending on the grid), or the grid could be using client side javascript to do the filtering, but the dataset from a server perspective is gone.  Based on your code, it looks like you are caching the dataset in the GlobalVars object to keep the dataset instantiated accross http calls and as the mechanism to communicate accross modules.  Caching datasets will limit scalability in that you are using memory (and lots of it depending on the number of rows in the dataset) to keep the dataset in scope accross roundtrips betwen the browser and the server.  Using DataTables will use a smaller footprint than a DataSet but are not able to have relationships between tables (Don't know if that is part of your requirement).  In addition, using DataTables is simply a band-aid to the underlying problem of caching result sets for users who may:

1) Walk away from their computer to get a cup of coffee and are still using what could be a large portion of your server resources

2) May never lick the "link" or "button" to generate the crystal report you mention and thereby are still using server resources

Also, I'm not sure what GlobalVars is, but is this truly global accross ALL users that hit your page?  if so, how does it work if user "A"'s query is totally different than user "B"'s query; or is this impossible (the same data is always displayed for all users).  If the data is the same for all users and if I truly understand your requirement, you will have many of these datasets depending on the module displayed.  If it's global (i.e. static), won't one modules dataset overwrite anothers in memory (GlobalVars.DS is overwritten if a user is viewing Module "A" and another user is viewing Module "B")? Or is this using the session framework to cache data? Storing the DataSet in viewstate also poses problems as the pagesize will get very large (depending on the DataSet size). 

Either way it could be expensive it terms of memory usage, network payloads, etc...  My suggestion would be to go back to the datasource.  I don't know your infrastructure and I know alot of .Net programmers and even Microsoft are afraid to "go all the way back to the database". But databases are VERY, VERY GOOD at retreiving and caching data, swapping least recently used data out of memory, and maintaining data "freshness".   Granted, you incur the penalty of a network trip (if the db server is on another server than your DNN installation and you also have to re-instantiate your data object).  It really is a case of how your users will TYPICALLY interact with your application.  If they always will click the link to generate the crystal report, caching is a good idea.  Be sure to dispose of the dataset after you are done with it to free memory.  If they seldom click the crystal report link, well, going back to the database may be your best solution.  In that case, could you simply pass the query used to instantiate the dataset (i.e. a string) to the reports module to display the report in crystal or can you make a "standard" property inside your grid module that contains the query and access that property from the reports module (I'm hacking here as I don't know how inter-module communication really works)?  Or you could store the query in viewstate and have the reports module access that viewstate variable to display the crystal report?  The query is bound to be smaller than a fully instantiated dataset which will keep the payload small but this poses a security problem because if I decode viewstate, I could learn all about how your database is structured from the query. 

Like I said, I could be way off in my assessment as I know very little of your actual requirements or how your users will interact with the system.


Version: DNN 4.4.1
Hosting Provider: 1and1
RAISE
 
New Post
5/25/2007 12:34 PM
 

First thanks for your help and time.

I am sorry but I think my code snippet was confusing.  I was trying to illustrate how I am passing the dataset between modules.  However the dataset is not created until the user clicks on the print "link" or "button" I save the filter parameters in a string and use those to recreate the dataset when the user prints the report. I am with you on the pitfalls of keeping the dataset instantiated; I had done some testing and quickly realized that would not work.

You bring up an interesting point about the global variables. I don't think its actually global to all users but its something I should test. They are basically public vars in a "common" module so I thought the vars would be session dependent not global.

I would tend to agree that normally the best solution would be going to the datasource but I could save myself a lot of work if I could come up with a better solution.

Here is the situation. I have a page that displays data to the users (in a grid).  What is displayed varies because there are filters on the page (filter by user, type, date range, location, etc.) The user also determines how to sort the data.  I use dynamic SQL to create my DB query in a stored procedure. I also use business objects between my UI and database. My business object has a find "Find" procedure that calls my "Find" stored procedure through my data provider. BLL.Find(parameter1 as datatype, parameter2 as datatype, etc.) So I actually don't have the query that was used to create the dataset available to me otherwise I could simply pass the SQL string. Now I maybe forced to do that but I think it would create a lot of extra work for me (and have security issues as you pointed out)

What I want to do is generalize it so that I can pass a dataset to the module (or datatable it that works) and a report name. The report module would load the report name and use the dataset to populate it.  I could then use this for different pages.  In fact thats what I doing now.  I call my reports module from about 5 other modules.

These modules all have different objects with different filters and so far seems to work but more tests need to be done (I only generate the dataset when necessary) What I'd like to know is the best way to pass data (dataset and or datatable) between modules.  Now in my case  the number of rows is not that large (maybe 2K) records at most and this application is an intranet but i am still cognizant of the speed/size issue.

In any case thanks again for your insight I appreciate it.

Martin

 

 

 
Previous
 
Next
HomeHomeUsing DNN Platf...Using DNN Platf...Administration ...Administration ...Pass dataset between modulesPass dataset between modules


These Forums are dedicated to discussion of DNN Platform and Evoq Solutions.

For the benefit of the community and to protect the integrity of the ecosystem, please observe the following posting guidelines:

  1. No Advertising. This includes promotion of commercial and non-commercial products or services which are not directly related to DNN.
  2. No vendor trolling / poaching. If someone posts about a vendor issue, allow the vendor or other customers to respond. Any post that looks like trolling / poaching will be removed.
  3. Discussion or promotion of DNN Platform product releases under a different brand name are strictly prohibited.
  4. No Flaming or Trolling.
  5. No Profanity, Racism, or Prejudice.
  6. Site Moderators have the final word on approving / removing a thread or post or comment.
  7. English language posting only, please.
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out
What is Liquid Content?
Find Out