I had a typed dataset with three tables in master-detail relationships and got the error "Failed to enable constraints. One or more rows contain values ciolating non-null, unique or foreign-key constraints." I couldn't figure out where the issue came from and finally simplified tho whole thing to this:
- New typed dataset containing one table only, named Contract.
- The table has only one field, named Contract Code which is a string with a MaxLength of 20. This field is marked as primary key.
- I created a new SqlDataAdapter and configured it using the wizard interface. The SQL is in this form: "select contract_code [Contract Code] from ContractList" and I unchecked the options for generating statements for update.
Then from my code, I use this:
sqlDataAdapter1.Fill(transactionsDataSet, "Contract");
When this executes, I get the exception as described above.
A couple of things that I have checked:
- The field must be primary key on the datatable because it will be used as foreign key. It is not, however, the primary key on the database even though it is always unique and never null.
- When I execute the SQL I configured in the SqlDataAdapter in SQL Management Studio, I get five rows with unique, non-null values.
- Initially, I had an error configuring the SqlDataAdapter, precisely because the table has no primary key. Fearing that some broken state may have remained, I deleted the adapter and created a brand new one. No change.
I have used SqlDataAdapter before, but always along with a SqlCommand, and always with SQL that I assign dynamically at run-time. Am I missing something about the IDE wizard, or does it have something to do with my table that doesn't have a key? Or something different altogether?
Update: I came across this post that shows a way to get the detail of what caused the constraint exception and it seems that it is failing on a null after fifteen of my five rows. Quite concerned about this I changed my code to the following:
try
{
sqlConnection.Open();
SqlCommand command = new SqlCommand(@"SELECT contract_code AS [Contract Number]
FROM contractlist", sqlConnection);
StringBuilder sb = new StringBuilder();
SqlDataReader reader = command.ExecuteReader();
int counter = 0;
while (reader.Read())
{
sb.AppendLine(reader.GetString(0));
counter++;
}
reader.Close();
sb.AppendLine(string.Format("{0} lines of data", counter));
textBox1.Text += sb.ToString();
SqlDataAdapter adapter = new SqlDataAdapter(command);
adapter.Fill(transactionsDataSet, "Contract");
}
catch (ConstraintException ex)
{
try
{
throw new DetailedConstraintException("error filling table", transactionsDataSet.Tables["Contract"], ex);
}
catch (Exception ex2)
{
textBox1.Text += ex2.Message;
}
}
For my trouble, I got the following text in my textbox:
0000814-1-1 0000814-6-2 0000814-8-3 0000814-8-4 0000814-8-5 5 lines of data error filling table Errors reported for WindowsFormsApplication2.TransactionsDataSet+ContractDataTable [Contract] Columns in error: [1] [Contract Code] - rows affected: 60 Row errors: [1] [Column 'Contract Code' does not allow DBNull.Value.] - rows affected: 60
So I definitely only get five, unique, non-null records. But for some reason, things go wrong when I fill.
Another update: When I link the TransactionsDataSet to a DataGridView and allow nulls on the field, I get five rows with null values. So even though the DataReader manages to read my values just fine, the values disappear when inserting into the dataset.