ViewSet_Define_Fill_Update
---------------------------------------------------------------
Demonstrates the basic functionality of the C1DataViewSet component.

This sample explains the basic functionality of the C1DataViewSet component.
Namely, it depicts how to define C1DataViewSet to work against an ADO.NET 
typed DataSet, fill it with data and commit changes made by the user back
to the database server.


C1DataViewSet tuning in design-time

First, the typed DataSet named NwindDataSet, working against the Access 
NWind.mdb sample database, was created using the "Data/Add New Data Source" 
menu item of VS IDE, where all tables from NWind database were included. 

From the Toolbox, C1DataViewSet (given the name c1DataViewSet1) and NwindDataSet 
(given the name nwindDataSet1) components were then dropped on a form (Form1)
, and c1DataViewSet1.DataSet property was set to nwindDataSet1.

Two views (C1DataView objects) were added to the c1DataViewSet1 with a 
master-detail relationship between them using the C1DataViewSet Editor. 
To open the Editor, click the arrow above the C1DataViewSet component to bring up 
the C1DataViewSet Tasks menu and select Edit. In the Editor click the "Add View" 
button, and select the "Orders" DataTable in the 
"Select a base DataTable for a single table view..." combobox and press OK. 
The C1DataView object is created and has the Definition property value
set as follows:
"SELECT * FROM Orders"
, i.e., defines a view which is based on a single "Orders" DataTable from
the nwindDataSet1 dataset.
In the Property window of the Editor change the ViewName property value of 
the C1DataView to "OrdersView".

Now add a child (detail) view for the newly created OrdersView view. In the 
C1DataViewSet Editor select an item representing the OrdersView view, press 
the "Add child view" button and enter the text:
"SELECT * FROM [Order Details] JOIN Products"
into the "... or specify definition statement for a composite view"
textbox. Alternatively, you could set the view definition using the 
"Definition Statement Builder", which is opened by pressing the
"Definition Builder..." button. Press the OK button to finish view creation
and set its ViewName property to OrdDetProductView.
OrdDetProductView.Definition property is set to:
"SELECT * FROM [Order Details] JOIN Products",
, i.e., defines a composite view based on "Order Details" and "Products"
DataTable(s) from the nwindDataSet1 DataSet, representing a rowset constructed
as a join of these tables (this is possible because "Order Details" and "Products"
tables have a DataRelation between them defined in the nwindDataSet1 DataSet).

The master-detail relationship between these views means that 
OrdDetProductView at any moment represents only those rows which are children 
for the currently selected row from OrdersView, and that foreign key of 
OrdDetProductView (OrderID column) will be automatically populated with 
primary key value of the current OrdersView row when a new row is added to 
the OrdDetProductView view.
Note that to define a relationship between views we only defined a parent and
child C1DataView, no more details were provided. This is enough because C1DataViewSet
will automatically detect that there is a DataRelation defined in NwindDataSet 
between the "Orders" DataTable (base DataTable of OrdersView view) and the
"Order Details" DataTable (one of the base tables of OrdDetProductView view)
and will establish a relationship based on that DataRelation.

Finally, bind UI controls to C1DataView objects defined in this C1DataViewSet. 
Two DataGrid(s) showing a content of views are defined as follows:
dataGrid1.DataSource = c1DataViewSet1;
dataGrid1.DataMember = "OrdersView";

dataGrid2.DataSource = c1DataViewSet1;
dataGrid2.DataMember = "OrdDetProductView";

Also, two textboxes are added showing the current definition of each view, which 
allow you to change the definitions in run-time.


Fill views with data

No steps are needed for this, just run the project and you'll see that views are
filled automatically.

As a result, c1DataViewSet1 fills underlying base DataTable(s) of nwindDataSet1
which are referenced in the views ("Orders", "Order Details" and "Products" in
this example) and builds rowsets of views based on the content of those tables.
All other DataTable(s) of nwindDataSet1 stays empty.


Idle foreign key constraints suppression

Note that the EnforceConstraints property of nwindDataSet1 is set to true, which 
results not all of the tables of DataSet are filled, but notice you didn't 
get an exception concerning foreign key constraint violation, which is the case, 
for example, for "Orders" (filled) and "Customers" (empty) DataTables of nwindDataSet1.
Meanwhile, foreign key constraint between "Orders" and "Order Details" tables
(both filled) still works, as well as other types of constraints. 
This is because C1DataViewSet performs automatic management of "idle" FK 
constraints, i.e., constraints between a filled table and its parent empty table.
For such tables C1DataViewSet automatically turns off FK constraints. Later, if the parent
table is filled with data, this constraint will be turned on again.
For example, if new C1DataView with the Definition "SELECT * FROM Customers"
is added to c1DataViewSet1, the constraint between the "Customers" and "Orders"
tables will be turned on automatically.

This behavior allows the use of a single typed DataSet, which references all of the 
tables from the database, with turned on constraints throughout the project, 
taking into account that in most applications only a subset of 
tables is filled with data from the server.


Commit changes, Autoincremented Primary Key refresh

Using the top DataGrid (dataGrid1), add a new row to the OrdersView and set the 
CustomerID column value to "ALFKI". Primary key column OrderID automatically takes a value
of -1 because the AutoIncrementSeed and AutoIncrementStep properties of OrderID
DataColumn are set to -1 in the NwindDataSet designer (negative values are set
just for clarity, it's not mandatory).

Then switch to the bottom DataGrid (dataGrid2), add a new row to the OrdDetProductView
view and set UnitPrice to 2, Quantity to 3 and ProductID to 12. OrderID
column, the foreign key of relation between views, automatically gets 
the value of -1, the same as PK of parent row. 

Now press the "Commit changes" button, which has the following event handler code:
c1DataViewSet1.Update();
, and you'll see that OrderID column values in both views have been
updated with values generated on database server. You can ensure that
records were added to database and that OrderID column of "Order Details"
table has a correct value corresponding to OrderID value of newly added
"Orders" table row.

C1DataViewSet.Update method automatically determines the correct order in which
rows should be committed to the server. It also refreshes client row columns with new 
values generated on the server, including the cases of server generated autoincrement
columns in conjunction with master-detail relationships between tables.


Update view definitions in run-time

You can change definition statements of views at run-time by typing them in 
the corresponding TextBox controls and pressing the corresponding "Update Definition"
button.
