10.1 Constraint Object Overview

The System.Data.Constraint type is an abstract class with two derived classes: UniqueConstraint and ForeignKeyConstraint. In order to use a constraint, you must create the appropriate class and add it to the DataTable.Constraints collection.

Constraints are enforced only if the EnforceConstraints property of the containing DataSet is true, which it is by default. If you attempt to modify, delete, or insert data in such a way that it violates an existing constraint, and EnforceConstraints is true, a ConstraintException is thrown, and the change is rejected. Similarly, if the DataTable already contains data, and you add a new Constraint, all the rows are checked to ensure they agree with the new rule. If any row violates the constraint, an InvalidConstraintException is thrown, and the Constraint object isn't added.

Here are a few more rules of thumb that come into play when working with Constraint objects:

  • If you have set DataSet.EnforceConstraints to false, you will never encounter a ConstraintException or InvalidConstraintException. However, if you later change DataSet.EnforceConstraints to true, all the rows will be examined to ensure that they don't violate the existing constraints. If a discrepancy is found, an InvalidConstraintException is thrown, and EnforceConstraints is set to false.

  • When merging a DataSet, constraints are applied and verified after the merge is complete.

  • There is no limit to how many Constraint objects a DataTable can contain; you are free to define as many unique rows and foreign key restrictions as you need.

It doesn't seem possible for .NET developers to create custom .NET constraint classes. The Constraint object defines several abstract methods that have assembly-level protection, so they can be overridden only by classes in the System.Data.dll assembly. However, you can create a class that handles the DataTable.ColumnChanging event to implement custom validation, as explained in Chapter 7.

    Part I: ADO.NET Tutorial
    Part II: ADO.NET Core Classes
    Part III: API Quick Reference