Ed Giardina's .NET Blog

Blogging about Hobbyist Adventures in C#, XNA, ASP.NET and other stuff

"Failed to Enable Constraints" Error, and the Zen of DataSets

If you're like me, you love the TableAdapters feature of Visual Studio 2005. Simply right-click on the App_Code folder, add a new item, and choose DataSet. Then pick a database to model it against, and BAM! A Strongly typed data object is built for you on the fly. This model enhances portability for the code we write at my company, since we have a core set of tools that look at different models depending on where you are in my company. (Texas has a different application running their operations versus us here in Boston. Therefore, their data model is different. I could write two datasets and one presentation layer to cover both.)

Anyways, So I went a little DataSet-crazy by making a TableAdapter for every View we use (essentially, every business object has its own Table Adapter). Then I wrote accessor-methods to get the data out of the TableAdapter depending on the Report (some reports filtered by X, others by Y, etc).

However, one of the methods I was calling was failing pretty badly.

1
ReportDataIndex.DataSource = T.GetDataGroupByWeek(ReportDate.SelectedDates[0]);

Seems pretty simple, right? ReportDataIndex is a GridView, and T is an instance of my TableAdapter. But every time I ran it, I got an exception: Failed to enable constraints. One or more rows  contain values violating non-null, unique, or foreign-key  constraints.

I read and read and read, and couldn't figure it out. A few forums recognized the problem, such as this article about DataSets, but none specifically mentioned the problem as it could have related to TableAdapters. I couldn't turn off 'EnforceConstraints' on my GridView, and I really struggled. I tried wrapping the Query Columns with 'ISNULL()' but that didnt' work either. I restricted my data results from the DB to only include non-nulls, and it was still failing.

After much soul-searching, I found the issue: If you create additional accessor-methods to your DataSet, their column count has to match the TableAdapter column count. Any columns not mentioned in your addtional method is passed back into the DataSet object as NULL. That's why the Fill was failing. Now, when I build my accessor-method and Query in the designer, it should throw an error and not let me save the DataSet / Compile. However, no pre-compilation is done with this regard on the XML document generated by the DataSet designer.

This is kind of limiting and if you have a TableAdapter that has two methods, one to get rows and one to get DISTINCT subset of rows, it can really cause problems. However, this small flaw is no reason to abandon DataSets and TableAdapters, as they are still great for rapidly prototyping data structures in your application

Comments

MaryMary said:

I am alive to you...although I am just an infant (about a year old now).

Found this post after banging my head for days and trying all the recommendations.  You'll never guess what worked for me on my C# WinForms/SSEE project!  I read that sometimes the XSD just cannot refresh and, so, it can cause issues.  When I wasn't getting the "Constraints" error, I was hit with the "MaxLength violated" error.  Anyway, I create a new project, added the same data source, added the columns (detail view) to the form and hit ctrl-f5.  Voila!  There were the two records that refused to load in my old project...followed by a successful Add a record!  I was getting very discouraged thinking that I must be such a newbie that I could not do what every other .NET programmer was doing...even though I have a decade and a half IT experience.  Whew!  On to the next learning curve.

# September 7, 2007 11:10 PM

Michael Brettell said:

I hit this same error, but all I did was modify the dataset query so that instead of a field having "Total Days:", it now had "Total Days Avail.:"  I had to give the column a new name to get it to work.  I guess it didn't like me increasing the size of the column...

# October 11, 2007 2:10 AM

MaryMary said:

OK, I see now why mine would've worked anyway since I was creating a new project.  

But I'm wondering whether we could have our additional accessor-methods' column count match the TableAdapter and then just mark those as columns as visible=false in the binding navigator "Edit Columns" screen?  I'll have to give that a try.

# October 20, 2007 4:45 PM

Dave Chamberlain said:

I've been bit by this several times and finally hit on a solution that does not require changing my underlying stored procs or query at all.  Go the GUI view of the TableAdapter and right-click on the column names that CAN be NULL in the database.  View the properties and set AllowDBNull = true and NullValue to Empty.  In my case the NullValue action was to throw an exception.

# January 10, 2008 9:43 PM

David Winchester said:

Hi - Thanks for the article.

I have been pulling out what little hair I have left, 'cause of this problem.

Anyways - my solution to get around this was just create another TableAdpater for the subset of data, not elligant I know but have wasted about 1 day looking into this and can't afford to spend anymore time.

Just good to know - I ain't the only person with this issue.

Dave

# April 14, 2008 4:14 PM

Mike said:

Thanks so much for this post.  You've saved me and others a lot of headache trying to figure this out. :)

# June 7, 2008 2:44 PM

Mike said:

Also, Dave Chamberlain's suggestion is right on the money:  check your "default value" properties for each column name in the TableAdapter GUI.  Set them to a default value where possible.  As Dave mentioned, the properties default to "throwing an exception" and for the string values you can set that to "empty."  That worked for my situation, in addition to setting my default integer values as 0.  :)

# June 7, 2008 3:34 PM

Left Brain Logic said:

Failed to enable constraints. One or more rows contain values violating non-null, unique, or foreign-key constraints

# November 9, 2008 6:56 PM

dtb said:

Ran into this myself. The cause in this case was unprintable characters in a character column that was part of a primary key.

# November 13, 2009 1:21 AM
Leave a Comment

(required) 

(required) 

(optional)

(required) 


Please add 7 and 6 and type the answer here: