Building a DataSet Programmatically
Problem
You want to build a DataSet programmaticallyincluding adding tables, columns , primary keys, and relationsfrom a schema that you have designed.
Solution
The following example shows how to build a complex DataSet programmatically, including how to build and add tables, columns, primary key constraints, relations, and column mappings. Use this as a template for building your own DataSet .
The sample code creates a DataSet . A DataTable object is created representing the Orders table in Northwind. Columns are added, including the auto-increment primary key, to the table. The table is added to the DataSet . The process is repeated for a DataTable representing the Order Details table in Northwind. A DataRelation is created relating the two tables. Finally, the tables are filled with data from Northwind.
The C# code is shown in Example 2-2.
Example 2-2. File: BuildDataSetProgramaticallyForm.cs
// Namespaces, variables, and constants using System; using System.Configuration; using System.Data; using System.Data.SqlClient; // . . . // Create the DataSet. DataSet ds = new DataSet("MyDataSet"); // Build the Orders (parent) table. DataTable parentTable = new DataTable("Orders"); DataColumnCollection cols = parentTable.Columns; // Add the identity field. DataColumn column = cols.Add("OrderID", typeof(System.Int32)); column.AutoIncrement = true; column.AutoIncrementSeed = -1; column.AutoIncrementStep = -1; // Add the other fields. cols.Add("CustomerID", typeof(System.String)).MaxLength = 5; cols.Add("EmployeeID", typeof(System.Int32)); cols.Add("OrderDate", typeof(System.DateTime)); cols.Add("RequiredDate", typeof(System.DateTime)); cols.Add("ShippedDate", typeof(System.DateTime)); cols.Add("ShipVia", typeof(System.Int32)); cols.Add("Freight", typeof(System.Decimal)); cols.Add("ShipName", typeof(System.String)).MaxLength = 40; cols.Add("ShipAddress", typeof(System.String)).MaxLength = 60; cols.Add("ShipCity", typeof(System.String)).MaxLength = 15; cols.Add("ShipRegion", typeof(System.String)).MaxLength = 15; cols.Add("ShipPostalCode", typeof(System.String)).MaxLength = 10; cols.Add("ShipCountry", typeof(System.String)).MaxLength = 15; // Set the primary key. parentTable.PrimaryKey = new DataColumn[] {cols["OrderID"]}; // Add the Orders table to the DataSet. ds.Tables.Add(parentTable); // Build the Order Details (child) table. DataTable childTable = new DataTable("Order Details"); cols = childTable.Columns; // Add the PK fields. cols.Add("OrderID", typeof(System.Int32)).AllowDBNull = false; cols.Add("ProductID", typeof(System.Int32)).AllowDBNull = false; // Add the other fields. cols.Add("UnitPrice", typeof(System.Decimal)).AllowDBNull = false; cols.Add("Quantity", typeof(System.Int16)).AllowDBNull = false; cols.Add("Discount", typeof(System.Single)).AllowDBNull = false; // Set the primary key. childTable.PrimaryKey = new DataColumn[] { cols["OrderID"], cols["ProductID"] }; // Add the Order Details table to the DataSet. ds.Tables.Add(childTable); // Add the relationship between parent and child tables. ds.Relations.Add("Order_OrderDetails_Relation", parentTable.Columns["OrderID"], childTable.Columns["OrderID"], true); // Fill the tables from the data source. SqlDataAdapter da; String sqlText; sqlText = "SELECT OrderID, CustomerID, EmployeeID, OrderDate, " + "RequiredDate, ShippedDate, ShipVia, Freight, ShipName, " + "ShipAddress, ShipCity, ShipRegion, ShipPostalCode, ShipCountry " + "FROM Orders"; da = new SqlDataAdapter(sqlText, ConfigurationSettings.AppSettings["Sql_ConnectString"]); da.Fill(parentTable); sqlText = "SELECT OrderID, ProductID, UnitPrice, Quantity, Discount " + "FROM [Order Details]"; da = new SqlDataAdapter(sqlText, ConfigurationSettings.AppSettings["Sql_ConnectString"]); da.Fill(childTable);
Discussion
The steps to build a complex DataSet programmatically, as shown in the code for the solution, are:
- Design the DataSet identifying the tables, columns, indexes, constraints, and data relations that need to be created.
- Create a new DataSet , naming it in the constructor.
- Create a new DataTable , naming it in the constructor.
- Add a column to the ColumnCollection of the table using the Add( ) method exposed by the Columns property of the DataTable specifying the name and data type of the column. If the column is a character-type column, define its maximum length. If the column is an auto-increment column, set the AutoIncrement property to true and set both the AutoIncrementSeed and AutoIncrementStep properties of the column to -1 . (For more information about using auto-increment columns, see Recipe 4.1). Repeat step 4 for each column in the table.
- Define the primary key for the table by setting the PrimaryKey property of the DataTable to the array of primary key DataColumn objects.
- Add the new table to the DataSet using the Add( ) method of the DataTableCollection exposed by the Tables property of the DataSet .
- Repeat steps 3-6 for each table in the DataSet .
- Create a data relationship between two related tables in the DataSet by using the Add( ) method of the DataRelationCollection exposed by the Relations property of the DataSet . Specify the relationship name, the related columns, and whether constraints are to be created when calling the Add( ) method. Repeat step 8 for each data relationship in the DataSet .
The steps continue, demonstrating how to fill the new DataSet :
- To fill the DataSet with data from the data source, create a DataAdapter defining the SQL select statement and the connection string in the constructor.
- Use the Fill( ) method of the DataSet to fill the table. Specify the table name to be filled in the second argument of the Fill( ) method.
- Repeat steps 9 and 10 for each table to be filled. See Recipe 2.1 for information about how to fill related tables from the data source without raising constraint violation errors.
Категории