Adding Restrictions to DataTable and DataColumn Objects As you know, a DataSet object is used to store a copy of a subset of the database.. In addition to storing rows retrieved from a d
Trang 1Adding Restrictions to DataTable and DataColumn Objects
As you know, a DataSet object is used to store a copy of a subset of the database For example, you can store a copy of the rows from database tables into a DataSet, with each table represented by a DataTable object A DataTable stores columns in DataColumn objects
In addition to storing rows retrieved from a database table, you can also add restrictions
to a DataTable and its DataColumn objects This allows you to model the same
restrictions placed on the database tables and columns in your DataTable and
DataColumn objects For example, you can add the following constraints to a DataTable:
• Unique
• Primary key
• Foreign key
In addition, you can add the following restrictions to a DataColumn:
• Whether the column can accept a null value-which you store in the AllowDBNull property of the DataColumn
• Any auto-increment information-which you store in the AutoIncrement,
AutoIncrementSeed, and AutoIncrementStep properties of the DataColumn You set these properties when adding rows to a DataTable with a corresponding
database table that contains an identity column The ProductID column of the Products table is an example of an identity column
Note ADO.NET will not automatically generate values for identity columns in a new row Only the database can do that You must read the generated
identity value for the column from the database You'll see how to do that later in the sections "Retrieving New Identity Column Values" and "Using Stored Procedures to Add, Modify, and Remove Rows from the Database." Also, if your database table contains columns that are assigned a default value, you should read that value from the database This is better than
setting the DefaultValue property of a DataColumn because if the default
value set in the database table definition changes, you can pick up the new value from the database rather than having to change your code
• The maximum length of a string or character column value-which you store in the MaxLength property of the DataColumn
• Whether the column is read-only-which you store in the ReadOnly property of the DataColumn
• Whether the column is unique-which you store in the Unique property of the DataColumn
Trang 2By adding these restrictions up front, you prevent bad data from being added to your DataSet to begin with This helps reduce the errors when attempting to push changes in your DataSet to the database If a user of your program attempts to add data that violates
a restriction, they'll cause an exception to be thrown You can then catch the exception in your program and display a message with the details The user can then change the data they were trying to add and fix the problem
You also need to define a primary key before you can find, filter, and sort DataRow objects in a DataTable You'll learn how to do that later in the section "Finding, Filtering, and Sorting Rows in a DataTable."
Tip Adding constraints causes a performance degradation when you call the Fill()
method of a DataAdapter This is because the retrieved rows are checked against your constraints before they are added to your DataSet You should therefore set the
EnforceConstraints property of your DataSet to false before calling the Fill()
method You then set EnforceConstraints back to the default of true after the call to
Fill()
You can use one of following ways to add restrictions to DataTable and DataColumn objects:
• Add the restrictions yourself by setting the properties of your DataTable and DataColumn objects This results in the fastest executing code
• Call the FillSchema() method of your DataAdapter to copy the schema
information from the database to your DataSet This populates the properties of the DataTable objects and their DataColumn objects automatically Although simple to call, the FillSchema() method takes a relatively long time to read the schema information from the database and you should avoid using it
You'll learn the details of both these techniques in the following sections
Adding the Restrictions Yourself
You can add restrictions to your DataTable and DataColumn objects yourself using the properties of the DataTable and DataColumn objects
For example, assume you have a DataSet object named myDataSet that contains three DataTable objects named Products, Orders, and Order Details that have been populated using the following code:
SqlCommand mySqlCommand = mySqlConnection.CreateCommand();
mySqlCommand.CommandText =
"SELECT ProductID, ProductName " +
Trang 3"FROM Products;" +
"SELECT OrderID " +
"FROM Orders;" +
"SELECT OrderID, ProductID, UnitPrice " +
"FROM [Order Details];";
SqlDataAdapter mySqlDataAdapter = new SqlDataAdapter();
mySqlDataAdapter.SelectCommand = mySqlCommand;
DataSet myDataSet = new DataSet();
mySqlConnection.Open();
mySqlDataAdapter.Fill(myDataSet);
mySqlConnection.Close();
myDataSet.Tables["Table"].TableName = "Products";
myDataSet.Tables["Table1"].TableName = "Orders";
myDataSet.Tables["Table2"].TableName = "Order Details";
The primary key for the Products table is the ProductID column; the primary key for the Orders table is the OrderID column; and the primary key for the Order Details table is made up of both the OrderID and ProductID columns
Note You must include all the columns of a database table's primary key in your query if
you want to define a primary key on those columns in your DataTable
In the following sections, you'll see how to
• Add constraints to the Products, Orders, and Order Details DataTable objects
• Restrict the values placed in the DataColumn objects of the Products DataTable
Adding Constraints to DataTable Objects
In this section, you'll see how to add constraints to DataTable objects Specifically, you'll see how to add primary key constraints to the Products, Orders, and Order Details
DataTable objects A primary key constraint is actually implemented as a unique
constraint You'll also see how to add foreign key constraints from the Order Details to the Products and Orders DataTable objects
Constraints are stored in a ConstraintCollection object that stores Constraint objects You access the ConstraintCollection using the DataTable object's Constraints property To add
a new Constraint object to ConstraintCollection, you call the Add() method through the Constraints property The Add() method allows you to add unique constraints and foreign key constraints to a DataTable Since a primary key constraint is implemented as a
unique constraint, you can also use the Add() method to add a primary constraint to a DataTable You'll see how to use the Add() method shortly
Trang 4You can also add a primary key constraint to a DataTable object by setting its
PrimaryKey property, which you set to an array of DataColumn objects that make up the primary key An array is required because the primary key of a database table can be made up of multiple columns As you'll see in the examples, this is simpler than using the Add() method to add a primary key constraint
CALLING THE Fill() METHOD OF A DataAdapter MORE THAN ONCE
The Fill() method retrieves all of the rows from the database table, as specified in your
DataAdapter object's SelectCommand property If you add a primary key to your
DataTable, then calling the Fill() method more than once will put the retrieved rows in your DataTable and throw away any existing rows with matching primary key column values already in your DataTable
If you don't add a primary key to your DataTable, then calling the Fill() method more than once will simply add all the retrieved rows to your DataTable again, duplicating the rows already there
This is another reason for adding a primary key constraint to your DataTable because you don't want duplicate rows
Adding a Primary Key to the Products DataTable
Let's take a look at adding a primary key to the Products DataTable First, the following example creates a DataTable object named productsDataTable and sets it to the Products DataTable retrieved from myDataSet:
DataTable productsDataTable = myDataSet.Tables["Products"];
Now, the primary key for the Products database table is the ProductID column; therefore, you need to set the PrimaryKey property of productsDataTable to an array containing the ProductID DataColumn object The following example shows how you do this It creates
an array of DataColumn objects named productsPrimaryKey and initializes it to the ProductID column of productsDataTable, then sets the PrimaryKey property of
productsDataTable to the array:
DataColumn[] productsPrimaryKey =
new DataColumn[]
{
productsDataTable.Columns["ProductID"]
};
Trang 5productsDataTable.PrimaryKey = productsPrimaryKey;
When you set the PrimaryKey property of a DataTable, the AllowDBNull and Unique properties of the DataColumn object are automatically changed as follows:
• The AllowDBNull property is changed to false and indicates that the DataColumn cannot accept a null value
• The Unique property is changed to true and indicates that the DataColumn value
in each DataRow must be unique
In the previous example, therefore, the AllowDBNull and Unique properties of the ProductID DataColumn are automatically changed to false and true, respectively
Adding a Primary Key to the Orders DataTable
The following example sets the PrimaryKey property of the Orders DataTable to the OrderID DataColumn:
myDataSet.Tables["Orders"].PrimaryKey =
new DataColumn[]
{
myDataSet.Tables["Orders"].Columns["OrderID"]
};
Notice I've used just one statement in this example to make it more concise than the previous example
You can also use the Add() method to add a unique, primary key, or foreign key
constraint to a DataTable The Add() method is overloaded as follows:
void Add(Constraint myConstraint) // adds any constraint
void Add(string constraintName, DataColumn myDataColumn,
bool isPrimaryKey) // adds a primary key or unique constraint
void Add(string constraintName, DataColumn parentColumn,
DataColumn childColumn) // adds a foreign key constraint
void Add(string constraintName, DataColumn[] myDataColumn,
bool isPrimaryKey) // adds a primary key or unique constraint
void Add(string cosntraintName, DataColumn[] parentColumns,
DataColumn[] childColumns) // adds a foreign key constraint
where