Fundamentally, you can think of a ProDataSet as an in-memory data store that holds a set of related records and is aware of their relationships. You now know that you can pass a ProDataSet as a single object from one session to another. Typically, this would be from an AppServer session where the necessary database connections or other data sources are available, to a client session where there is a user interface or other code that uses and possibly updates the data. The client session could be an ABL session (for example one running WebClient), or a non-ABL session (for example a Microsoft .NET application).
In a typical interaction, a client-based session requests a ProDataSet from the server as a result of a UI event, such as the user requesting the data for a particular purchase order. The client runs a procedure on the server that has the PO number as an INPUT parameter and the PO ProDataSet as an OUTPUT parameter.
On the server side, the application procedure typically provides a static definition for the ProDataSet, attaches Data-Sources to the ProDataSet's buffers, and executes a FILL operation to load a set of related data for the PO into the ProDataSet. It then returns the ProDataSet to the caller on the client.
The client session receives the ProDataSet as an OUTPUT parameter into its own ProDataSet definition. It then makes the ProDataSet available to the user interface. Individual temp-tables might be displayed in different browses and individual records from a table displayed in a Viewer or single-record frame where record detail is displayed and updated. The client can update different records in any of the ProDataSet's tables, add records to some tables (such as new OrderLines for the PO), and delete other records. Lists of lookup codes that are part of the ProDataSet can be displayed, in browses of their own or in drop-down lists, and cached on the client for future use within that session. Some of the updates and other user interactions could require additional calls to the AppServer for validation or for additional information. This is all application-dependent.
When the user is finished making a set of changes, a client procedure runs another procedure on the server that accepts the changes made to the ProDataSet as an INPUT-OUTPUT parameter. If the ProDataSet contains a large number of records that have not been changed, then the client can return only changed records and their before-images to reduce the amount of data sent across the network. Typically, the original ProDataSet is no longer available on the server when the changes are passed back. This is especially true when the environment uses a stateless AppServer connection, which is the norm for most modern applications. The server-side procedure reads the contents of the ProDataSet, and possibly other parameters that accompany it, and applies changes to the data sources based on the before-image records in the ProDataSet that indicate what the changes were.
The server procedure then performs any required validation of the data. This normally is encapsulated in a server-side logic procedure. The server procedure can pass errors and other server-side changes made to the records back to the client.
This is the basic client-to-server round-trip scenario. This works more or less exactly the same whether the client is an OpenEdge session or a .NET session. The following figure illustrates this scenario.
Figure 2. Typical client/server round trip with a ProDataSet
The second basic use case is for strictly server-side business logic. In this scenario, a business logic procedure on the server uses one or more ProDataSets to access the application data it needs to look at. The ProDataSets encapsulate the data in a standard way, insulating the logic from the actual structure of the data sources. They also apply update validation logic and other ProDataSet behavior in a standard, consistent way. The business logic therefore fills a ProDataSet with data it needs to see or change, and then applies updates back to the database. This is somewhat different from the individual FIND, FOR EACH, and ASSIGN statements an application would typically use today to access various tables it needs to look at, but this change in programming standards reflects the degree of encapsulation we are trying to achieve. In this second type of use case, there is no need for client/server interaction or passing ProDataSets between sessions. The ProDataSet is strictly being used to encapsulate data definition, data access, and update logic in a standard way. This is an essential part of a stable, future-proof application architecture.
There are many other types of use cases as well, including:
Using update events and custom business logic procedures to provide validation logic on both the client and server, where the client-side logic is restricted to what can be evaluated without direct database access
Building a ProDataSet from a set of complex calculated data, such as a price sheet, that is expensive to derive from the original data sources but needed for frequent reference once it is loaded
Using a ProDataSet as a mechanism to pass a number of different but possibly unrelated tables of data, such as lookup values, to the client session to use in building lookup lists or validating client field values